- 操作系统相关
- 进程与线程:
- 一个进程至少包含一个线程,多个线程共享进程的内存空间(寄存器、堆栈、上下文);
- 进程是资源分配和调度的基本单位,线程是cpu调度的基本单位;
- 进程创建fork();线程创建是pthread_create();
- 进程摧毁会删除其中所有线程;而线程摧毁不会影响其他线程;
- 线程的私有属性:线程id、寄存器、线程控制块TCB、栈空间
- 进程的私有属性:进程id、进程控制块PCB
- 多线程要注意内存的保护,利用互斥锁、读写锁、信号量、条件变量机制;编写难度较高;
- 多线程占用内存比多进程要低;
- 进程空间:顺序从低地址到高地址:
- 文本段、程序段、TXT段:存放编译过的二进制代码;只读;共享内存;线程安全;
- Data段:在程序运行前已被初始化的全局变量;
- bss段:在程序运行前未被初始化的全局变量;
- 堆:手动分配;malloc、calloc等;
- 栈:从上往下自动分配内存;存储代码执行时的临时变量;存储函数执行的入口地址;
- 进程间通信、线程间通信:
- 进程间通信方式
- 管道:半双工通信,一个流动方向;只能用于父子进程/兄弟进程;
- 有名管道FIFO:半双工通信,可以用于任意进程间;
- 消息队列:独立于读数据和写数据;有不同的消息优先级;
- 共享内存:最快,需要信号量同步;
- 信号量:有一个可用资源,如果为0阻塞;不为0,则可用资源-1;
- socket:不同机器进程间通信;
- 线程间通信:
- 互斥量:
- 读写锁:有读锁和写锁;
- 信号量:
- 条件变量:满足条件后通过signal函数通知进程
- 原子操作:不会被线程调度打断的操作;可以是多个操作步骤;
- 进程间通信方式
- Linux常用命令
- Linux目录分析
- /bin :保存常见命令
- /boot :保存linux系统启动相关的文件,首先加载
- /dev :存放设备文件,外设、usb驱动等
- /etc :存放软件配置文件,安装samba过程中,会修改/etc/samba/samba.conf文件;
- /home :最常使用,每个用户默认空间在该目录下;
- /lib :保存系统的动态链接库;
- /media:光盘挂载点;
- /mnt:系统挂载点,一般插优盘需要挂载在这里;
- /proc :文件系统,保存所有文件信息,注意设备也是文件;如cpu、内存、io端口等;
- /root :root用户目录;
- /tmp:临时目录;
- /usr:系统软件安装目录;
- /var:动态文件/数据,如log文件;
- 编译过程
- 预处理:(1)将宏定义展开;(2)将头文件插入;(3)处理条件预编译指令;(4)删除注释;(5)添加行号;(6)保留#pragma 编译器指令;
- 编译:(1)词法分析(2)语法分析(3)语义分析(4)源代码优化
- 汇编:转换为汇编语言
- 链接:未解决符号重定位
- 静态链接:编译时完成;需要的函数被复制到相关位置;利用ar cr libxxx.a xx.o命令生成;
- 动态链接:程序运行时重定位;g++ -fPIC(位置无关) -shared libXXX.so XXX.o命令生成;
- 静态链接执行速度快,但是动态链接占用内存少,更有利于共享内存;
- 程序升级问题:静态链接改动就得重新编译,动态链接接口不变就不需要改动;
- 进程与线程:
- 网络相关
- TCP三次握手
- A发送SYN=n的包,进入SYN_SEND状态;
- B返回一个SYN+ACK的包,SYN=m,ACK=n+1,进入SYN_RECV状态;
- A返回一个ACK包,ACK=m+1,进入established状态;B收到这个ack或者收到数据报文时进入established状态;所以三次握手最后一次可以丢包;
- TCP四次挥手
- A发送FIN包,进入FIN_Wait_1状态;
- B返回ACK包,进入Close_Wait状态;A收到这个ACK包后,进入FIN_WAIT_2状态;
- B发送FIN包,进入LAST_ACK状态;
- A收到FIN包,发送ACK包,进入TIME_WAIT状态;B收到ack后关闭进入closed状态;A等待2MSL时间后close;2倍的最大报文生存时间;30s,60s等;
- TCP字段
- 基本20字节,最多能扩展到60字节
- 2字节源端口号,2字节目的端口号
- 4字节SYN序列号
- 4字节ACK序列号
- 4位字段总大小offset,6位保留位,syn+ack+fin+org(紧急指针)+psh+rst(重连)标志包类型位;2字节滑动窗口;
- 2字节的校验和;2字节的紧急指针;
- 网络IO模型
- 四种IO模型
- 阻塞IO模型:执行recvfrom()函数后,阻塞,直到数据读到用户空间;
- 非阻塞IO模型:执行recvfrom()函数后,如无数据,立刻返回状态;循环执行查询操作,直到有数据,阻塞,数据读到用户空间;
- 多路IO模型:利用select/poll/epoll等函数阻塞查询有无数据,可以轮循的方式查询到多个链接;查询到后调用read函数阻塞获取数据;
- 异步IO模型:执行read函数,通知内核一个回调函数,立刻返回去做其他事务;内核收到数据,将数据拷贝到用户空间后,回调通知用户;
- 注意:前三种为同步IO模型,数据都是用户阻塞从内核空间拷贝;而异步IO是内核完成这件事情;
- select函数:fd标识符保存在一个bitmap中,总数受限;fd每次使用完成后需要清零重新赋值;需要完成用户空间到内核空间的fd的拷贝;
- poll函数:fd标识符保存在结构体数组中,总数相对select大很多;不需要重新赋值;需要完成用户空间到内核空间的fd的拷贝;
- epoll函数:fd保存在结构体数组中,但是内存通过mmap映射到内核空间,相当于内存共享,不需要完成用户空间到内核空间的fd的拷贝;同时只处理活跃的fd,不同于select和poll要全部遍历fd;
- 四种IO模型
- TCP拥塞控制
- 五层模型--从浏览器输入到获取内容,中间经历了什么?
- 域名解析:浏览器缓存、本地缓存、递归查询
- 构建HTTP请求包;
- 进行TCP连接,三次握手;
- 发送HTTP请求包--五层模型,逐层传递;
- 服务器返回一个重定向地址;返回1/3;
- 服务器返回页面框架,本地浏览器进行渲染;
- 继续请求页面中的其他元素;
- close连接;
- 负载均衡技术:
- HTTP重定向技术:负载均衡服务器;用户向该服务器请求时,服务器返回一个其他服务器的IP地址;302状态码;两次请求才能获取内容;--应用层
- DNS解析:在DNS服务器上为一个域名配置了多个IP地址;--应用层
- 先进行DNS均衡负载,在进行HTTP重定向;
- 应用层反向代理服务器:类似于重定向,但是它可以缓存部分常用数据;---应用层
- 数据链路层:均衡负载服务器修改mac地址,这样真正的服务器不用通过均衡负载服务器发送数据,而可以直接发送;
- TCP三次握手
- 算法相关
- 求链表中点:快慢指针
- 求无序数组第K大数:快速排序
- 二叉树求最长路径:DFS+全局变量,求字树深度;
- 数据结构相关
- 数组和链表
- 都是顺序存储结构
- 数组地址空间连续,链表地址空间不连续
- 增:数组O(1)扩容O(n)、链表O(1)删:数组O(n)、链表O(1)改:数组O(1)、链表O(n)-O(1)查:数组O(1)、链表O(n)
- 数组插入、删除数据较慢;查找数据较快;
- 栈和队列
- 可以用数组也可以用链表
- 栈有一个指针,指向栈顶
- 队列两个指针,一个队首,一个队尾
- 栈先进后出,队列FIFO
- map底层实现:更多的是存储一个映射关系,有的需要排序,用数组实现更好一些;
- hashmap将<key,value>作为一个node节点存储;
- 利用hash(key)计算数组存储位置,每个位置处可能是一个链表;
- 内存不够时进行扩容,重新计算位置;
- hash冲突:
- 开放定址法:线性探测、二次探测、随机探测
- 再次hash法:不同的hash函数
- 链地址法:hashmap
- LRU缓存设计:需求put()、get()
- 需要删除中间、最末尾元素:链表
- 添加元素
- 读取元素:用hash定位
- 数组和链表
- c/c++语言相关
- 写memcpy()函数:注意地址覆盖
- inline函数
- 用于函数体较短时,避免复杂的环境变量入栈操作、PC计数器、寄存器等;
- 直接将函数体展开到调用函数的位置;
- 与宏定义的区别:宏定义编译器不进行检查,inline函数会检查;
- static关键字
- 修饰变量:只能初始化一次,占用的静态变量区,不是栈,不随函数退出而销毁;
- 修饰函数:只能在本文件中使用,其他文件不能引用;
- 修饰对象成员:所有对象公用这一个成员,属于类,不属于某个具体的对象;
- 修饰成员函数:操作静态成员变量;
- const关键字
- 修饰一个变量,表明不可修改;
- 修饰函数参数:函数中该参数/该参数指向的内容不可修改;
- const只修饰后面的变量,注意*要跟后面的连起来;
- 多态、虚函数
腾讯暑期实习面试问题总结--后台开发方向
最新推荐文章于 2021-03-12 09:48:55 发布