面经
HT . WANG
Think Twice , Code Once
展开
-
秋招总结(先后拿到百度ACG,腾讯CSIG)
准备秋招,可能大家都比较关心这一点以下是几点建议,快来围观把!!!(1)尽早投简历,投的越早,机会越多。提前批有些大厂是没有笔试阶段的,这样会减少大部分难度,当然这个时候HC也是最多的时候,一定要冲,管他会不会呢,你要知道没有什么是你都会的,只有在面试中不断受挫折积累经验才可以积累更多经验。(2)刷题必须搞,《剑指offer》一定要刷,这些题基本上就是你面试过程中手撕代码的题目,时间充足的话可以再去牛客网或者leetcode上再刷一些,我个人的话从2020年12月到2011年7月一共刷了387道原创 2021-10-24 20:42:44 · 3765 阅读 · 0 评论 -
面试中常被问到(26)菱形继承及解决方法
菱形继承菱形继承属于多继承中一种具有代表性的继承关系,产生数据冗余和数据二义性问题class A{public: int a;};class B : public A{public: int b;};class C : public A{public : int C;};class D : public B, public C{public: void func() { }};上述代码中对变量进行内存查看 如下图:解决方法..原创 2021-09-01 17:43:22 · 2200 阅读 · 0 评论 -
面试中常被问到(25)map和pair区别
1,pair的类型:pair是一种模版类型。每个pair 可以存储两个值。这两种值的类型没有限制,也可以自定义类型。2、pair 应用:如果一个函数有两个返回值的话,如果是相同类型,就可以用数组返回,如果是不同类型,两个属性的话,就可以用pair 进行操作map可以当做一个容器(装载具有一定格式的数据);pair可以理解为元素(放入到容器的的每个个体),pair并没有单独行动的典型用法,正常都是配合map来使用(即把pair这个元素插入到map这个容器里面)。...原创 2021-08-05 21:10:03 · 5691 阅读 · 1 评论 -
面试中常被问到的(12)函数调用执行过程
第一步:函数调用 1、将函数调用语句下一条语句的地址保存到在栈中,以便哈数调用完成后返回。(将函数放到栈空间中称为压栈)。 2、对实参表从后向前,一次计算出实参的值,并且将值压栈。 3、跳转到函数体处。 第二步:函数体执行 4、如果函数体中定义了变量,将变量压栈 5、将每一个形参以栈中对应的实参值取代,执行函数体的功能体。 6、将函数体中的变量、保存到栈中的实参值,依次从栈中取出,释放栈空间(出栈)。 第三步:返回...转载 2021-07-25 09:30:58 · 3230 阅读 · 1 评论 -
面试中常被问到的(24)网络分层及协议
OSI七层网络模型:应用层 表示层 会话层 传输层 网络层 数据链路层 物理层TCP/IP五层网络模型:应用层:负责应用程序之间数据沟通 HTTP/HTTPS/DNS协议 传输层:负责进程(socket)之间数据传输 TCP/UDP协议 网络层:负责地址管理和路由选择(源端对端IP地址) IP协议 设备:路由器 网络层负责为分组网上的不同主机提供通信,将传输层交下来的报文封装为IP数据报 数据链路层:负责相邻设备之...原创 2021-07-17 16:34:53 · 2806 阅读 · 1 评论 -
面试中常被问到的(23)协议解析中http与https
HTTP:首先明白,什么是http协议?超文本传输协议,也就是明文字符串传输协议特点如下:http协议在传输层基于tcp实现,是一个简单的请求/响应协议,支持C/S模式 客户端向服务端发起请求时,只需要传入请求方法和请求资源路径(请求方法+URL)简单快捷,搭建http服务器规模小,通信速度快 http通过对头部content-Type修改,控制传输数据类型,允许传输任意类型的数据对象 无连接保证每次连接只处理一个请求。服务端处理完客户请求,并收到客户应答后便断开连接http协议格式首行原创 2021-07-16 16:11:52 · 1836 阅读 · 0 评论 -
面试中常被问到的(22)TCP三次握手/四次挥手及问题
TCP三次握手: 连接:客户端:发送syn请求,收到服务端ack确认,连接建立服务端:监听syn请求,收到客户端syn请求新建套接字进行ack回复,确认连接建立状态:客户端:SYN_SEND->EATABLISHED服务端:LISTEN->SYN_RCVD->ESTABLISHED TCP四次挥手 连接:主动关闭方:发送FIN请求,关闭主动方发送数据功能(接收数据依然存在)并收到确认关闭,再次收到被动方FIN请求进行回复确认,等待一段之间...原创 2021-07-15 14:44:54 · 1686 阅读 · 0 评论 -
面试中常被问到的(21)TCP/UDP如何保持可靠性
基于连接 tcp通信首先要建立连接,确保通信双方都具有收发数据的能力 序列号,确认应答,超时重传 tcp协议中有序号和确认序号,确保数据有序传输,同时序列号也为后续超时重传提高基础数据达到接收方,接收方会发出一个确认应答,表示已经收到了该数据,并且确认序号说明下一次需要接受的数据序列号如果长时间未收到确认应答,认为发送数据丢失,发送方会等待一定间隔时间再次重传 窗口控制与快速重传 滑动窗口的目的是解决发送数据过快过多导致接收方缓冲区满溢而丢包问题,实现流量控制此时,...原创 2021-07-14 17:31:46 · 1926 阅读 · 0 评论 -
面试中常被问到的(20)select,poll,epoll对比
从以下四个角度进行对比:用户态将文件描述符传入内核的方式(1)select:创建三个文件描述符集并拷贝到内核中,分别监听 读,写,异常动作(2)poll:将传入struct pollfd结构体数组(包含需要监控的描述符及对应事件以及返回实际就绪事件)拷贝到内核中(3)epoll:调用epoll_create接口,在内核缓冲区中建立一棵红黑树以及双链表,向内核中添加需要监控的文件描述符,在红黑树增加对应节点内核态检测文件描述符读写状态的方式(1)select:采用轮询遍历,遍历所有文件描述原创 2021-07-13 15:40:59 · 1784 阅读 · 0 评论 -
面试中常被问到的(19)常见几种锁
互斥锁:mutex,在任何时刻,只能有一个线程访问该对象,当获取锁操作失败,线程会进入睡眠(等待队列中被挂起)直至等待锁释放被唤醒读写锁:分为读锁和写锁,处于读操作时,可以允许多个线程同时获得读操作,但是同一时刻只能有一个线程获得写锁,其他线程获取写锁失败被挂起等待,直至写锁释放被唤醒当有一个线程获得写锁在写时,读锁也不能被其他线程获取一旦有写者,则后续读者必须等待,唤醒时优先考虑写者自旋锁:任何时刻只能有一个线程访问对象当获取锁失败,不会进入睡眠,而是会原地自旋,直到锁被释原创 2021-07-10 16:32:43 · 1593 阅读 · 0 评论 -
面试中常被问到的(18)父子进程,孤儿进程及僵尸进程
并发:单核cpu多任务,宏观同一段时间内表现出同时运行,微观上实际为时间片轮转,同一时刻只能有一个进程占据cpu资源运行,多个任务执行存在先后顺序并行:多核cpu多任务,严格物理意义上的同时运行,多个任务运行在不同核上,相互之间不影响(1)父子进程子进程通过父进程创建,子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程什么时候结束。当子进程退出的时候,内核会释放子进程所有资源,包括打开的文件,占用的内存等。但是依然会保留部分信息(进程id,退出状态,运行时间),直到原创 2021-07-09 17:19:55 · 2038 阅读 · 0 评论 -
面试中常被问到的(17)多线程及多进程优缺点
多进程: 优点:进程资源相互独立,互不干扰,子程序崩溃不影响主程序的稳定性。进程比较稳定健壮 通过增加cpu核心数,可以很容易扩充性能 尽量减少线程加锁解锁的影响,极大提高性能 每一个进程可以获得本地全部地址空间和相关资源,性能上限很大缺点:逻辑控制复杂,需要与主程序进行交互 需要跨进程边界,对大量数据传输不友好,适合小数据量传输,密集运算会导致调度开销增大 单cpu轮询并发处理,多cpu并行处理 多线程与多进程结合,每一个cpu开启一个子进程,每一个子进程开启若干同类型数据进..原创 2021-07-09 15:52:38 · 2228 阅读 · 0 评论 -
面试中常被问到的(16)进程间通信方式
Linux下进程间通信方式主要包括:信号,管道,信号量,消息队列,共享内存,socket 信号: 是一种事件通知机制,或者说是一种事件中断机制,通过信号通知当前进程发生了什么事件,中断进程当前操作去执行另外一个事件触发的操作信号生命周期:产生,注册,注销,处理(1)产生:硬件产生(按键eg:ctrl+c,ctrl+z)软件产生(执行命令:kill -信号索引 进程id)(2)注册:让进程知道自己收到了哪些信号(节点:添加信号信息节点 位图:标记哪些信号待处理)可靠信号:无论是...原创 2021-07-08 10:32:12 · 1746 阅读 · 0 评论 -
面试中常被问到的(15)死锁发生及解决
首先要明白什么是死锁?死锁:多个进程或线程访问一组竞态资源的时候,出现永久阻塞的问题 死锁发生条件: 互斥:进程对所分配的资源不允许其他进程访问,若被其他进程访问,只能等待直至占用该资源的进程使用完成后释放该资源 请求与保持:进程获得一定资源后,又对其他资源发起请求,但是请求资源可能被其他线程占用,此时请求阻塞,与此同时该线程也不会释放自己已经占用的资源 不可抢占:进程已获得的资源在未使用完成之前,不可以被其他线程抢占剥夺,只能在自己使用完成后自己释放资源 循环等待:进程死锁后,必然存在原创 2021-07-06 17:38:09 · 1613 阅读 · 0 评论 -
面试中常被问到的(14)虚存管理和虚拟地址空间
虚拟内存技术使得每一个进程在运行过程中,始终都是显式独自占用当前系统内存资源,事实上,所有进程共享同一个物理内存,每一个进程只把自己目前需要的虚拟内存空间映射在物理内存上,此过程内核并不会立即把虚拟内存对应位置的程序数据和代码拷贝到物理内存中,只是建立一种虚拟映射关系,程序运行时通过此映射关系动态拷贝数据。malloc也是内核为其分配虚拟内存,为这块虚拟内存对应的页表项做相应设置,当进程真正访问到此数据时,才可触发缺页异常 虚存优点: (1)虚拟内存技术扩大了各自进程的地址空间(2)每个进原创 2021-07-06 16:44:55 · 1721 阅读 · 0 评论 -
面试中常被问到(13)五种IO模型
阻塞IO:发起IO调用,若发现IO未就绪(IO条件不具备),则一直等待 也就说条件不满足一直死等非阻塞IO:发起IO调用,若发现IO未就绪,则直接报错返回应用程序通过recvfrom调用不断和内核交互,当条件未达到会直接返回,然后不断轮询,不停去询问内核数据条件是否满足,如果条件满足数据准备好了,则把数据从内核空间拷贝到用户数据空间中。如果条件不满足,数据没有准备好,内核会向应用程序报错,隔断时间应用程序再次调用recvfrom发起请求,间隔的这段时间中,应用程序可以做自己的事信号驱动.原创 2021-07-05 18:39:10 · 1746 阅读 · 0 评论 -
剑指offer笔记(11)位运算
二进制中1的个数最简单的方法就是,依次右移,再与1& 根据&的结果判断是否为1int NumOf1(int n){ int count=0; while(n) { if(n&1) count++; n=n>>1; } return count;}我们都知道右移一位等价于整数除以2,那么此处是否可以用除法代替呢?除法效率要比移位运算的效率低得多,一般都...原创 2021-06-28 16:44:09 · 1529 阅读 · 0 评论 -
剑指offer笔记(十)递归和循环
递归和循环什么是递归?递归就是在一个函数内部调用函数本身什么是循环?循环通过设置计算初始值及终止条件,在此范围内重复计算举例说明一下:1+2+3+...+n求和//循环int sum(int n){ int res=0; for(int i=1;i<=n;i++) { res+=i; } return res;}//递归int sum(int n){ return n==0?0:n+sum(n-原创 2021-06-28 15:50:47 · 1522 阅读 · 0 评论 -
面试中常被问到(12)进程与线程的区别
什么是智能指针?智能指针的本质就是一个类,当超出类的作用域,类会自动调用析构函数,析构函数会自动释放资源,因此智能指针的目的就是当手动申请空间后在程序结束时会自动释放内存空间,不需要手动释放,即使忘记释放也会避免内存泄漏常见智能指针: auto_ptr unique_ptr shared_ptr weak_ptr ...原创 2021-06-28 14:49:30 · 1575 阅读 · 0 评论 -
面试中常被问到(11)虚函数/纯虚函数
虚函数 如何定义一个虚函数?在基类成员函数前加入virtual关键字,但并不代表此函数不被实现,只是说明允许基类指针调用派生类重写的此函数一个类只要声明有虚函数或者从基类继承了虚函数,在编译过程中就会生成虚函数表,虚函数表存储在数据段,只能读,不能写,和常量字符串在同一内存段上,生命周期是整个应用程序的生命周期构造函数任何时候不可以声明为虚函数虚函数表是在对象构造知乎才建立的,调用构造函数,还没有实例化对象,也就没有存放虚函数表的地址空间析构函数可以声明为虚函数面试中常被问到(五)C+..原创 2021-06-23 17:07:26 · 1779 阅读 · 0 评论 -
面试中常被问到(十)左/右值引用
左/右值引用 概念: 左值:能对表达式取地址,或匿名对象/遍历。可能出现在=左边,表达式结束后依然存在的持久对象 右值:不能对表达式取地址,或匿名对象。只能出现在=右边,表达式结束后就不在存在的对象(一般右值为常量,临时变量,匿名对象,局部变量等) 左/右值引用区别: 左值可以寻址,右值不可以 左值可以被赋值,右值不可以被赋值,但可以给左值赋值 左值可变,右值不可变 普通引用只能引用左值,不能引用右值 const引用既可以引用左值,又可以引用右值 c++11右值引用只能引用右值原创 2021-06-23 16:13:51 · 1776 阅读 · 0 评论 -
剑指offer笔记(九)栈和队列
栈:先进后出队列:先进先出 用栈实现队列 通过两个栈,利用先进后出的特性循环得到先进先出的特性class MyQueue {public: stack<int> pushst; stack<int> popst; /** Initialize your data structure here. */ MyQueue() { } /** Push element x to the back of qu原创 2021-06-22 16:30:48 · 1499 阅读 · 0 评论 -
面试中常被问到(九)STL迭代器失效问题
STL容器中迭代器失效的场景:以vector为例进行分析vector进行数据插入如果空间充足那组,插入数据后,原有数据向后移动,导致迭代器失效 如果空间不足,插入新数据需要扩容,则发生拷贝,导致迭代器失效void reverse(size_t n) { if (n > capacity()) { //保存有效元素个数 size_t sz = size(); //申请空间 T* tmp = new T[n]; //拷贝原有空间 if .原创 2021-06-22 15:30:45 · 1805 阅读 · 1 评论 -
剑指offer笔记(八)重建二叉树
题目:根据一棵树的前序遍历与中序遍历构造二叉树前序遍历:根 -> 左 -> 右前序遍历:根 -> 左 -> 右原创 2021-06-21 16:10:30 · 1521 阅读 · 4 评论 -
面试中常被问到(八)STL标准库容器分类
顺序容器 vector:向量容器,类似于数组功能,但比数组更灵活,底层是动态开辟的一维数组,内存可自增,每次默认增值2倍原创 2021-06-21 14:27:53 · 1581 阅读 · 0 评论 -
剑指offer笔记(七)从尾到头打印链表
如果面试中给你一个链表的头结点,要求你从尾到头打印链表中每一节点的值,你该如何去考虑这个问题呢?自然而然想到两种解决思路:其一就是改变链表结构,gaibi原创 2021-06-18 14:54:19 · 1506 阅读 · 1 评论 -
面试中常被问到(七)封装继承多态知多少
面向对象(oop)面向对象技术三大特性:封装,继承,多态 封装 封装的概念体现在类抽象和对象实例化,封装就是将数据和对数据的操作封装在一个类中,用类对数据进行了抽象 继承 (1)如果两个类的关系存在一种所属关系,则可以把二者一个作为基类,一个作为派生类(2)继承的本质就是代码复用,在继承关系中,如果派生类没有明确显示定义“构造,拷贝构造,析构,赋值运算符重载,取地址操作符重载,const修饰的取地址运算符重载”这6个函数,会自动合成,除构造和析构外,其余所有成员均可继承为派生类所原创 2021-06-17 17:09:51 · 2050 阅读 · 1 评论 -
面试中常被问到(六)new/delete和malloc/free区别
new/delete和malloc/free区别(1)二者都是用来实现动态内存管理,内存空间的开辟(new,malloc)以及内存空间的释放(delete,free)(2)malloc/free是C/C++标准库函数,new/delete是c++操作符(3)malloc/free只是动态分配内存空间,释放空间,而new/delete除了分配空间还会调用构造析构函数进行初始化与清理(4)malloc/free需要手动计算类型大小且返回值为void* new/delete可自己计算类型的大小.原创 2021-06-16 14:58:31 · 1450 阅读 · 0 评论 -
剑指offer笔记(六)字符串空格替换
字符串空格替换题目:实现一个函数,把字符串中的每一个空格替换为“%20”,eg:we are happy 替换为we%20are%20happy由原来一个空格字符,替换之后变成%,2,0三个字符,因此替换之后的字符串会变长此时需要考虑是否在原字符串基础上进行修改如果不考虑内存空间是否充足,可以直接考虑再开辟一块空间进行新字符串存放,基于C++STL模板类直接进行遍历,遇到空格替换添加至新串即可,代码如下:class Replacement {public: string repl..原创 2021-06-16 14:19:20 · 1387 阅读 · 0 评论 -
剑指offer笔记(五)字符串注意事项
字符串注意事项(1)C语言中字符串的表述通过:若干个字符组成序列,形成一个字符数组组成一个字符串,由于字符串使用频率高,为了方便使用,C++为字符串制定模板类,STL中有string类,列举了字符串常见属性的一些操作 (2)C/C++中每个字符串都以字符'\0'结尾,以此作为字符串结束的标志,但需要注意的是,由于这个额外字符的开销,字符串边界问题需要谨慎考虑,以免越界char str[10];strcpy(str,"0123456789");上述代码没有考虑字符串结尾的额外字符,导致数组越界原创 2021-06-16 13:22:57 · 1361 阅读 · 0 评论 -
剑指offer笔记(四)二维数组中的查找
二维数组中的查找题目:在一个二维数组中,每一行都按照从左到右的顺序递增,每一列都按照从上到下的顺序递增,判断一个数是否在数组中例如:1 2 8 9 2 4 9 12 4 7 10 13 6 8 11 15 如果对此类题型不是很了解的同学,拿到这个问题,脑海里蹦出的第一个思路就是逐个数字比较,分三种情况:相等,结束查找过程 若<target 则i++,j++ 在右边和下边继续找 若>t...原创 2021-06-15 16:55:29 · 1367 阅读 · 0 评论 -
面试中常被问到(五)C++析构函数,虚析构函数
C++析构函数(1)对于析构函数:析构函数与构造函数相呼应,从调用构造函数开始到自动执行析构函数二者调用期间即为所创建对象实例的生命周期。(2)析构函数与类名相同,仅前面加一个~,一般析构函数无参,且无返回值,析构函数具有唯一性,不可重载(3)若用户没有自定义析构函数,编译器会默认自动生成一个缺省析构函数,即使用户自定义析构函数,在底层编译器依然会在自定义析构函数的基础上再次调用默认析构函数(4)如果一个类中定义有指针,且在使用的过程中动态申请了内存空间,一般建议在调用析构函数前显式释放内存原创 2021-06-15 15:43:14 · 1873 阅读 · 0 评论 -
剑指offer笔记(三)菜鸟程序猿和高级攻城狮码赋值运算符函数的区别
赋值运算符函数小小的一个赋值运算符函数的写法完全可以区分出一个程序猿的功底运算符函数是C++中经典的运算符重载函数对于给定一个类:class my_string{public: my_string(char* pData=NULL);//带默认参数构造 my_string(const my_string& str);//拷贝构造 ~my_string();//析构privat: char* m_pData;};无论菜鸟程序猿还是高级攻城狮原创 2021-06-14 15:39:32 · 2533 阅读 · 2 评论 -
面试中常被问到(四)C/C++中数组,指针和引用的区别
C/C++中数组,指针和引用的区别数组和指针:数组 指针 保存数据 保存数据地址 可直接访问元素的值 间接访问(首先获取指针内容作为地址,通过寻址找到元素的值) 一般大小固定,数据类型相同 一般用于动态数据结构 隐式的分配和删除 通过malloc分配内存,free释放内存 sizeof得到数组大小 sizeof得到指针大小,默认指针大小为4字节 数组名表示数组存放首地址 指针指向即为数据存放地址 指针和引用:指针 引用原创 2021-06-14 12:21:42 · 1569 阅读 · 0 评论 -
剑指offer笔记(二)sizeof
在面试过程中,经常会被面试官问到sizeof相关问题比如面试官会问到:定义一个空的类型,里面没有任何成员变量和成员函数,对该类型求sizeof,得到的结果是多少?结果是1,而不是0空类型的实例中确实不包含任何成员信息,直观来看,sizeof结果就是0,但是当我们声明该类型的实例的时候,它必须在内存中占有一定的空间,否则将无法使用这些实例。此处sizeof结果为1是由vs编译器决定的,vs中规定:每个空类型的实例占用1个字节的空间如果添加一个构造函数和析构函数后,sizeof的大小会不会变化?原创 2021-06-11 16:20:12 · 1511 阅读 · 2 评论 -
面试中常被问到(三)c/c++区别
c/c++区别c是面向过程的语言,c++是面向对象的语言,现如今都采用面向对象(oop)编程技术,为什么oop语言如此热门呢?比如像c++语言中,有封装(类及对象),继承和多态机制,此外c++还支持模板,运算符重载,异常处理机制.同时借助STL模板库,实现更为强大的功能 c由于面向过程的语言,程序设计也只是简单的面向过程,实现串行,而c++x面向对象的编程语言,可以有自己独特的设计模式,比如经典的单例设计模式 在动态内存管理上,二者也存在一定区别,c通过malloc和free完成,且二原创 2021-06-11 09:46:28 · 2091 阅读 · 1 评论 -
面试中常被问到(二)对齐方式
对齐方式第一个成员变量在结构体偏移量为0的地址处 其他成员变量要对齐到对齐数的整数倍的地址处,对齐数=min(默认对齐数,成员大小) vs默认对齐数为8(x64)或4(x32) linux下gcc/g++默认对齐数为4 结构体总大小为最大对齐数的整数倍 如果嵌套结构体,嵌套结构体对齐到自己最大对齐数的整数倍处,结构体大小就是所有最大对齐数(包含嵌套结构体对齐数)的整数倍附:常见数据类型类型 位 范围 char 1 个字节 -128 到 127 或者 0 到 2..原创 2021-06-10 18:26:30 · 1394 阅读 · 0 评论 -
剑指offer笔记(一)c++中的关键字有哪些?
笔记(一)c++中的关键字有哪些? volatile关键字 由于常见的编译器会对其进行优化,release版本下,对一个变量值进行内存修改后,输出结果发现并未输出修改后的值volatile修饰一个变量后,表示该变量易变,每次在访问该关键字修饰的变量时都要读内存,不对其进行优化。 mutable关键字 类的常成员函数在语义上是不允许修改类的成员变量的,但是有时候可能根据代码的需要并不是这么绝对。使用mutable声明一个类的成员变量,它告诉编译器类的常成员函数可以修改这个变量。原创 2021-06-10 17:28:47 · 1526 阅读 · 0 评论 -
面试中常被问(一)static关键字
static关键字1在C语言中,static修饰的变量与全局变量类似,在程序编译时(程序运行前)加载到内存数据段上,其中细分为(bss段:存放未初始化的全局变量,data段:存放初始化的全局变量)2在c++语言中,对象的创建只有执行了构造函数之后才会完成,但static修饰的对象,在程序以运行就被创建(单例设计模式就基于此完成设计)静态变量 全局静态变量 内存中的位置:存储在静态存储区(数据段),且整个程序运行期间一直存在,生命周期与程序生命周期一致初始化:未经初始化的全局静态变量原创 2021-06-10 17:28:23 · 1498 阅读 · 0 评论