2022春招待学习【ing】

2022春招待学习

参考

算法和数据结构


  • 堆的插入删除实际上是怎么做的?堆的底层实现是什么?数组和下标模拟的树
  • 排序

C/C++ 语言特性和实现原理 【八股】

  • [x] 作用域以及namespace

    • 作用域https://zh.wikibooks.org/wiki/C%2B%2B/%E4%BD%9C%E7%94%A8%E5%9F%9F#%E5%85%A8%E5%B1%80%E4%BD%9C%E7%94%A8%E5%9F%9F
    • 块作用域(局部作用域){}、for、while、if、switch
    • 函数作用域
    • 函数原型作用域
    • 全局作用域
    • 文件作用域:通过typedef、class、struct、union、enum等方式声明或定义,如果不是内部类型,则名字都具有文件作用域
    • 命名空间作用域
    • 类作用域
    • 匿名类的作用域
    • namespace
    • 方便是用相同函数名的函数
  • [x] 指针、引用、数组、内存

    • 指针和引用的区别

    • 引用需要初始化,指针可以不初始化,因此指针使用的时候需要判断是不是空指针

    • 指针可以更改,引用不能更改,更改知识那个值改变了

    • 引用的使用可以一定程度避免“指针满天飞”的情况,但是C++中的引用只是C++对指针操作的一个“语法糖”,在底层实现时C++编译器实现这两种操作的方法完全相同。

    • int &a = 1;和int b = &a有什么区别?

    • int &a = 1;编译器无法通过,因为1无法进行取地址操作,无法对一个立即数取地址,因为立即数并没有在内存中存储,而是存储在寄存器中,可以通过下述方法解决:

      const int &a = 10;

      左值引用要求右边的值必须能够取地址,如果无法取地址,可以用常引用;
      但使用常引用后,我们只能通过引用来读取数据,无法去修改数据,因为其被const修饰成常量引用了。

    • 右值引用 &&

    • 为临时变量续命,也就是为右值续命,因为右值在表达式结束后就消亡了,如果想继续使用右值,那就会动用昂贵的拷贝构造函数。

    • 指针的引用知道嘛?

    • 没有指向引用的指针

      int v = 1;
      int &ri = v;  // 整型变量v的引用
      int *p = &ri; // 这是指向引用的指针吗?普通指针
    • 指针的引用 int* &x。主要是在函数参数中传递别用,用于修改变量本身,而不是局部修改

    • 内存

    • 内存中的堆和栈的区别

      • 从空间上和存放内容上来说:

      栈:内存空间小一些,栈的内存要远远小于堆内存,如果你使用递归的话,那么你的栈很快就会充满。如果递归没有及时跳出,很可能发生StackOverFlowError问题。主要存放函数体的地址、函数的参数、局部变量临时变量等。

      堆:内存空间大一些,主要存放一些通过new出来的对象或者malloc申请的内存空间。

      • 从申请释放方式上来说

      • 由编译器或者系统自动申请和回收,不受我们的控制。4

      • 分配的空间不连续,并且堆是为一个程序分配的,多个线程公用同一个堆内存。

    • new、delete 和 malloc、free 的区别

  • [x] C 和 C++ 的一些区别

    • 有新增的语法和关键字
    • C++ 中有重载和虚函数的概念
    • struct的区别
    • C++ 中增加了模板还重⽤代码,提供了更加强⼤的 STL 标准库。
  • [x] 虚机制:虚函数、纯虚函数 、虚函数表

    • 析构函数不能是虚函数的原因:为创建对象没有vptr指针,不能指向vtble,不能让表里的函数指针调用虚函数
  • [ ] 面向对象,掌握class相关的基础知识:构造、析构(拷贝构造、拷贝赋值、移动构造、移动赋值)、对象成员、继承和多态、基类的析构函数为什么需要时虚函数?(保证子类析构函数被调用)、explicit、友元

  • [ ] 什么是声明,什么是定义?

  • [ ] c++的三大特性:封装、继承、多态

    • 继承、虚继承、菱形继承等
    • 多态: 动态绑定,静态多态
  • [ ] 重写、重载

    • 操作符重载
  • [x] this指针

    首先来谈谈this指针的用处:【this指针实际上是编译器用来解析自引用的函数参数,vptr是一个真正的指针】

    (1)一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。

    (2)this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。

    其次,this指针的使用:

    (1)在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this。

    (2)当参数与成员变量名相同时,如this->n = n (不能写成n = n)。

    int get_age() const{
    
          return this->age;
      }
    Person& add_age(int a){
          age+=a;
          return *this;
      }

    this在成员函数的开始执行前构造,在成员的执行结束后清除。类中的get_age函数会被解析成get_age(const A * const this),add_age函数会被解析成add_age(A* const this,int a)。在C++中类和结构是只有一个区别的:类的成员默认是private,而结构是public。this是类的指针,如果换成结构,那this就是结构的指针了。

  • [ ] 智能指针

    • 原理:引用计数、RAII(资源获取即初始化)思想
    • 使用:shared_ptr、weak_ptr、unique_ptr等
    • unique_ptr和shared_ptr区别在哪里?
    • 学会使用make_unique
  • [x] 一些关键字的作用:static、const、volatile、extern、inline、union

    • [x] static

      • static的基本用法,文件中的static变量、static函数,函数下的static变量,类中的静态成员、静态函数、static 成员函数不能被 virtual 修饰(不属于任何类,是共享的,没有this指针,无法访问vptr)同时也不能被const 和 volatile关键字修饰
    • [x] const

      • const的用法,修饰指针,引用

      • 修饰指针本身,修饰指针所指的变量,修饰指针本身和指针所指的变量

      • 修饰引用,放在函数中,类加速

      • 三个const的区别

      class {
         const int fun(const int a) const {
         }
      };

      第一个,函数的返回值类型是const。 这个const修饰没什么意义;

      第二个,第二个代表是个const型的引用,就是这个a是可以引用一个int型变量,但是不可以改变这个变量的值(可以读值);但是不用传引用的话,完全没有意义,因为a本身就不可修改,加入引用的话,如果a是一个类,能加快传递速度不需要复制、构造等操作。

      第三个是表示不会修改它的数据成员,一般用在类的重载函数中;

      • Q:const和#define的区别

      • 编译器处理方式不同:define宏是在预处理阶段展开,const常量是编译运行阶段使用。

      • 类型和安全检查不同:define宏没有数据类型,不做任何类型检查,仅仅是展开;const常量有具体的数据类型,在编译阶段会执行类型检查。

      • 存储方式不同:const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而 #define定义的常量在内存中有若干个拷贝。

      • 从代码调试的方便程度而言:
        const常量可以进行调试的,define是不能进行调试的,因为在预编译阶段就已经替换掉了

    • [x] inline

      • 内联函数inline,相当于把内联函数里面的内容写在调用内联函数处,提高效率,但是不建议把很长的函数或者函数体内出现循环的函数写成内联
      • 虚函数不可以是内联函数?
      • 虚函数可以是内联函数,内联是可以修饰虚函数的,但是当虚函数表现多态性的时候不能内联。
      • 内联是在编译期建议编译器内联,而虚函数的多态性在运行期,编译器无法知道运行期调用哪个代码,因此虚函数表现为多态性时(运行期)不可以内联。
      • inline virtual 唯一可以内联的时候是:编译器知道所调用的对象是哪个类(如 Base::who()),这只有在编译器具有实际对象而不是对象的指针或引用时才会发生。
    • [x] union

      • 联合(union)是一种节省空间的特殊的类,一个 union 可以有多个数据成员,但是在任意时刻只有一个数据成员可以有值。当某个成员被赋值后其他成员变为未定义状态。联合有如下特点:
      1. 默认访问控制符为 public
      2. 可以含有构造函数、析构函数
      3. 不能含有引用类型的成员
      4. 不能继承自其他类,不能作为基类
      5. 不能含有虚函数
      6. 匿名 union 在定义所在作用域可直接访问 union 成员
      7. 匿名 union 不能包含 protected 成员或 private 成员
      8. 全局匿名联合必须是静态(static)的
    • [x] extern

      • 在 C 语⾔中,修饰符 extern ⽤在变量或者函数的声明前,⽤来说明 “此变量/函数是在别处定义的,要在此处引⽤”。
      • 编译器编译C和CPP后的函数名称不一样,为了C++和C互相调用
    • [x] volatile

      • volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素(操作系统、硬件、其它线程等)更改。所以使用 volatile 告诉编译器不应对这样的对象进行优化

      • volatile 关键字声明的变量,每次访问时都必须从内存中取出值(没有被 volatile 修饰的变量,可能由于编译器的优化,从 CPU 寄存器中取值)

      • const 可以是 volatile (如只读的状态寄存器)

      • 指针可以是 volatile

    • [x] explicit

      • explicit 修饰构造函数时,可以防止隐式转换和复制初始化

      • explicit 修饰转换函数时,可以防止隐式转换,但按语境转换除外

    • [x] enum

  • [ ] 四种类型转换:static_cast, dynamic_cast, const_cast, reinterpret_cast

  • [ ] STL部分容器的实现原理,如 vector、deque、map、hashmap

    • 哈希表怎么做到的O(1),桶,哈希函数
  • [ ] 函数模板,泛型编程

  • [ ] 模板特化、偏特化,萃取 traits 技巧

  • [ ] 编译链接机制、内存布局(memory layout)、对象模型

  • [ ] C++11 部分新特性,

    • 右值引用
    • 完美转发
    • auto
    • lambda表达式
    • lambda[](int a, int b)->bool{return a < b};这个是用来干嘛的?如果让你自己写一个简单的lambda可以吗?
  • [ ] 设计模式:单例、工厂等稍作了解

  • [ ] 好的代码应该具备什么样的特点?

  • [x] 位域:一种数据结构,可以让结构体中的指定成员只占几个bit,节省空间。


C++代码实操

  1. 基本类型、函数和容器的使用
  2. 进制转换及数字转字符snprintf
  3. 字符转数字stoi
  4. STL
    1. unordered_map:first,second,for (auto t =m.begin(); t != m.end(); ++t),count,m.find(元素)!=m.end(),erase,insert(make_pair(key, value))
    2. vector:如何创建m行n列初始化为0的数组,如何全排列(next_permutation),push_back,pop_back,front,back,insert,size,empty,erase,swap
    3. string:+-=<>,size,empty,insert,substr,c_str,replace,find,sort和下标
    4. queue相关:front,back,push,pop,size,empty,priority_queue优先队列(默认大堆顶,也可以自定义为小堆顶),stack,deque
    5. set,map:默认有序,对自定义结构需要自定义比较方法用于排序(延伸:如何自定义?)
      以上很多容器都具有迭代器,迭代器的使用是共通的,有的方法我可能只在一个容器下列了,但实际上很多容器都可以用,切记要主动实践,灵活使用。

网络编程

Linux 系统编程

操作系统

  • 进程与线程管理、内存管理、IO与文件系统、设备管理
  • 了解 Linux 内核部分实现原理,如内存管理、进程管理、虚拟文件系统等
    • 操作系统由哪些构成
    • 进程的状态、切换、调度
    • 进程间通信方式(共享内存、管道、消息)
    • 进程和线程的区别
    • 线程的实现方式(一对一、多对一等)
    • 互斥与同步(信号量、管程、锁)
    • 死锁检测与避免
    • 并发经典的问题:读者写者、哲学家就餐问题
    • 为什么需要虚拟内存,MMU 具体如何做地址转换的
    • 内存为什么分段、分页
    • 页面置换[算法]()
    • 文件系统是如何组织的
    • 虚拟文件系统(VFS)是如何抽象的
  • 《Linux内核设计与实现》
    • 这本书重点关注「第 3 章进程管理」、「第 5 章系统调用」、「第12章内存管理」、「第13章虚拟文件系统」、「第 15 章进程地址空间」 这些章节属于操作系统核心部分,其它如中断处理、块 IO、设备管理根据你自己兴趣选择看下就可以了。

编译、调试和测试

  • gtest单元测试
  • make、makefile

    计算机网络

数据库使用及原理

常见 NoSQL组件,如 Redis、Memcached

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇