最近一个月的招聘,主要是暑期实习的提前批,在这一个月里,接到了很多的电话面试和笔试邀请,也拿到了几个offer,所以在这里做一个阶段性总结,一方面说说面试和笔试经历,另一方面记录一下这段时间的准备过程。
19年毕业,所以准备应聘18年的暑期实习,博主中流985本硕计算机,应聘岗位为C++后台开发,从3月15号接到腾讯的内推电面开始,到现在4月12号,经历过的笔试有网易游戏,网易互联网,美团,京东,腾讯,小米。接到的面试有网易游戏,腾讯,阿里。
笔试题分为四种,单选,多选,编程,问答。单选和多选主要考察理论知识,比如操作系统,数据库,数据结构等 。编程题,一般不会很难,大多是经典算法题的变种。问答题,是题目设置生产场景,要求给出解决方案。
面试问题也可以分为三类,语言特性,理论知识,算法题。
举些例子:
C++语言特性:new/delete的底层实现,为什么构造函数不能为虚函数,写STL的compare函数时需要注意哪些。
理论知识:进程间通讯方式,TCP状态转换图,树的特性,构建堆的时间复杂度证明,大数据处理,高并发应对方案。
算法题:25匹马5条赛道找前三,一堆螺帽和螺母的匹配方法。
对于算法题没有很好的办法,建立先去刷一下<数据结构><剑指offer>等基础的算法书,然后再去leetcode上面去刷题,国内互联网公司,面试时问到的算法大部分是leetcode上medium水平的,hard难度的很少。对于算法思想,只要掌握,贪心,分治,动态规划即可,大部分的算法题都可以解决,还有些题是找规律,属于野路子。
这里针对面试经历,给出一些资料和书籍:
这些是专门为面试准备的书:
C++初级书籍, 不评价,太厚了,我没看过,但是像C++关键字比如const,static等,都在这本书上有。
C++晋级书籍,必看,整本都要过,中间有不懂的细节要去网上查清楚,做到精通。
unp,网络编程的经典书籍,必看,前半本细看,后半本随缘。要保证TCP,UDP套接字编程,epoll,select异步编程这两个知识点从原理到实现层面上完全掌握。
linux C++经典书籍,虽然我没看,但是有时间最好看一下,上面有关进程间的通讯方式要从原理上掌握。
<深入理解C++对象模型> C++高级书籍,必看,主要是前半本,深入理解C++的内存分配方式
C++高级书籍,必看,主要是前半本,了解STL容器的底层实现方式,以及内存分配机制。
计算机网络初级书籍,必看,主要讲基础的网络协议,要掌握每种网络协议的特点和用处,尤其是TCP状态转换图,要做到知其然也知其所以然。
没看过,主要是对http的基础知识要有所了解,比如说HTTP协议字段的特点等。
以下是大学教材部分,非科班的同学尤为要注意,科班同学只要过一遍加深一下印象即可。
<数据库系统概念> 教材,必看,理解数据库的基本原理,包括索引等。
<操作系统> 教材,必看,理解操作系统的基本原理,包括线程调度,内存管理,同步互斥等。
<数据结构> 教材,必看,理解基础的数据结构的特点和对应的算法,比如队列,栈,堆,树,B树及常见排序算法的原理等。
针对我面试时遇到的重点问题,下面是针对性的博客:
1.进程间通讯方式:https://blog.csdn.net/a1232345/article/details/41443079/
2.C++编译过程:https://blog.csdn.net/loude1992/article/details/77725238
3.为什么要内存对其:https://www.cnblogs.com/jijiji/p/4854581.html
4.函数指针和指针函数:http://nevel.cnblogs.com/p/6370264.html
5.线程间同步方式:https://blog.csdn.net/loude1992/article/details/70148079
6.MyIsam与InnoDB引擎的区别:https://blog.csdn.net/loude1992/article/details/78020285
7.深/浅拷贝:https://blog.csdn.net/loude1992/article/details/77947601
8.数据库事务,隔离级别:https://www.cnblogs.com/fjdingsd/p/5273008.html
9.死锁:https://blog.csdn.net/ls5718/article/details/51896159
10.内存管理和智能指针:
https://www.cnblogs.com/findumars/p/5929831.html?utm_source=itdadao&utm_medium=referral
11.类型转换函数:https://blog.csdn.net/loude1992/article/details/77944239
12.一次web请求的流程:https://www.cnblogs.com/lidong94/p/8309130.html
13.https流程:https://www.cnblogs.com/mddblog/p/6948980.html
14.基础的大数据处理方法:http://www.sohu.com/a/138204769_236714
15.linux常用命令:https://blog.csdn.net/zzcv_/article/details/2145362
16.linux进程状态:https://blog.csdn.net/sdkdlwk/article/details/65938204
17.红黑树特点,使用场景,平衡性
18,TCP为什么要三次握手,4次挥手
19.大端序和小端序的特点,应用场景,为什么你的电脑是小端序。
20.数据库三范式
21.什么情况下有默认构造函数,默认拷贝构造函数,默认=运算符
22.为什么构造函数不能使虚函数,为什么析构函数最好是虚函数
这是几个别人总结的经典面试题,上面的看完后可以来这里查漏:
https://www.cnblogs.com/bozhicheng/p/6259784.html
https://www.cnblogs.com/nancymake/p/6516933.html
最后面是知乎上的Oscarwin大大给出的C++后台面试要准备的内容,可以在准备的差不多以后对着这个单子来查漏。
总之就是多面多想多学
作者:Oscarwin
链接:https://www.zhihu.com/question/34574154/answer/253165162
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
C和C++语言基础
参考书籍:《C++ primer》,《effective C++》,《STL源码解析》,《深度搜索C++对象模型》
- extern关键字作用
- static关键字作用
- volatile是干啥的
- 说说const的作用,越多越好
- new与malloc区别
- C++多态性与虚函数表
- C++多态的实现?
- 虚函数的作用?
- 虚函数用于实现多态,这点大家都能答上来但是虚函数在设计上还具有封装和抽象的作用。比如抽象工厂模式。
- 动态绑定是如何实现的?
- 静态多态和动态多态。静态多态是指通过模板技术或者函数重载技术实现的多态,其在编译器确定行为。动态多态是指通过虚函数技术实现在运行期动态绑定的技术。
- 虚函数表
- 虚函数表是针对类的还是针对对象的?同一个类的两个对象的虚函数表是怎么维护的?
- 编译器为每一个类维护一个虚函数表,每个对象的首地址保存着该虚函数表的指针,同一个类的不同对象实际上指向同一张虚函数表。
- 纯虚函数如何定义,为什么对于存在虚函数的类中析构函数要定义成虚函数
- 析构函数能抛出异常吗
- 构造函数和析构函数中调用虚函数吗?
- 指针和引用的区别
- 指针与数组千丝万缕的联系
- 智能指针是怎么实现的?什么时候改变引用计数?
- 构造函数中计数初始化为1;
- 拷贝构造函数中计数值加1;
- 赋值运算符中,左边的对象引用计数减一,右边的对象引用计数加一;
- 析构函数中引用计数减一;
- 在赋值运算符和析构函数中,如果减一后为0,则调用delete释放对象。
- share_prt与weak_ptr的区别?
- C++四种类型转换:static_cast, dynamic_cast, const_cast, reinterpret_cast
- 内存对齐的原则
- 内联函数有什么优点?内联函数与宏定义的区别?
- C++内存管理
- STL里的内存池实现
- STL里set和map是基于什么实现的。红黑树的特点?
- STL里的其他数据结构和算法实现也要清楚
这个问题,把STL源码剖析好好看看,不仅面试不慌,自己对STL的使用也会上升一个层次。
- 必须在构造函数初始化式里进行初始化的数据成员有哪些
- 模板特化
- 定位内存泄露
(1)在windows平台下通过CRT中的库函数进行检测;
(2)在可能泄漏的调用前后生成块的快照,比较前后的状态,定位泄漏的位置
(3)Linux下通过工具valgrind检测
- 手写strcpy,memcpy,strcat,strcmp等函数
数据结构与算法
这一块考察范围太广,主要靠多刷题吧,牛客网,剑指OFFER,LeetCode等。
Hash表
- Hash表实现(拉链和分散地址)
- Hash策略常见的有哪些?
- STL中hash_map扩容发生什么?
(1) 创建一个新桶,该桶是原来桶两倍大最接近的质数(判断n是不是质数的方法:用n除2到sqrt(n)范围内的数) ;
(2) 将原来桶里的数通过指针的转换,插入到新桶中(注意STL这里做的很精细,没有直接将数据从旧桶遍历拷贝数据插入到新桶,而是通过指针转换)
(3) 通过swap函数将新桶和旧桶交换,销毁新桶。
树
- 二叉树结构,二叉查找树实现;
- 二叉树的六种遍历;
- 二叉树的按层遍历;
- 递归是解决二叉树相关问题的神级方法;
- 树的各种常见算法题(http://blog.csdn.net/xiajun07061225/article/details/12760493);
- 什么是红黑树?
- 红黑树与AVL树的区别
- Trie树(字典树)
链表
- 链表和插入和删除,单向和双向链表都要会
- 链表的问题考虑多个指针和递归
(1) 反向打印链表(递归)
(2) 打印倒数第K个节点(前后指针)
(3) 链表是否有环(快慢指针)等等。
栈和队列
- 队列和栈的区别?(从实现,应用,自身特点多个方面来阐述,不要只说一个先入先出,先入后出,这个你会别人也会,要展现出你比别人掌握的更深)
- 典型的应用场景
海量数据问题
- 十亿整数(随机生成,可重复)中前K最大的数
- 十亿整数(随机生成,可重复)中出现频率最高的一千个
排序算法
- 排序算法当然是基础内容了,必须至少能快速写出,快排,建堆,和归并
- 每种算法的时间空间复杂度,最好最差平均情况
位运算
布隆过滤器
几十亿个数经常要查找某一个数在不在里面,使用布隆过滤器,布隆过滤器的原理。布隆过滤器可能出现误判,怎么保证无误差?
网络与TCP/IP
参考书籍:《图解TCP/IP》,《TCP/IP详解 卷一》,《图解HTTP》,《HTTP权威指南》
- TCP与UDP之间的区别
(1) IP首部,TCP首部,UDP首部
(2) TCP和UDP区别
(3) TCP和UDP应用场景
(4) 如何实现可靠的UDP
- TCP三次握手与四次挥手
- 详细说明TCP状态迁移过程
(1) 三次握手和四次挥手状态变化;
(2) 2MSL是什么状态?作用是什么?
(3)三次握手为什么不是两次或者四次?
- TCP相关技术
- TCP重发机制,Nagle算法
- TCP的拥塞控制使用的算法和具体过程
- TCP的窗口滑动
- TCP客户与服务器模型,用到哪些函数
- UDP客户与服务器模型,用到哪些函数
- 域名解析过程,ARP的机制,RARP的实现
- Ping和TraceRoute实现原理
HTTP
- http/https 1.0、1.1、2.0的特点和区别
- get/post 区别
- HTTP返回状态码
- http 协议头相关
http数据由请求行,首部字段,空行,报文主体四个部分组成
首部字段分为:通用首部字段,请求首部字段,响应首部字段,实体首部字段
- https与http的区别?如何实现加密传输?加解密方式?
- 浏览器中输入一个URL发生什么,用到哪些协议?
安全相关
至少了解攻击的原理和基本的防御方法,常见的攻击方法有一下几种
- SQL注入
- XSS
- CSRF
- SYN洪水攻击
- APR欺骗
数据库
主要参考书籍:《数据库系统概念》,《高性能MySQL》
- SQL语言(内外连接,子查询,分组,聚集,嵌套,逻辑)
- MySQL索引方法?索引的优化?
- InnoDB与MyISAM区别?
- 事务的ACID
- 事务的四个隔离级别
- 查询优化(从索引上优化,从SQL语言上优化)
- B-与B+树区别?
- MySQL的联合索引(又称多列索引)是什么?生效的条件?
- 分库分表
Linux
主要参考书籍:《现代操作系统》,《APUE》,《UNP》,《LINUX内核设计与实现》,《深入理解LINUX内核》
(1) 进程与线程区别?
(2) 线程比进程具有哪些优势?
(3) 什么时候用多进程?什么时候用多线程?
(4) LINUX中进程和线程使用的几个函数?
(5) 线程同步?
在Windows下线程同步的方式有:互斥量,信号量,事件,关键代码段
在Linux下线程同步的方式有:互斥锁,自旋锁,读写锁,屏障(并发完成同一项任务时,屏障的作用特别好使) 知道这些锁之间的区别,使用场景?
- 匿名管道与命名管道的区别:匿名管道只能在具有公共祖先的两个进程间使用。
- 共享文件映射mmap
mmap建立进程空间到文件的映射,在建立的时候并不直接将文件拷贝到物理内存,同样采用缺页终端。mmap映射一个具体的文件可以实现任意进程间共享内存,映射一个匿名文件,可以实现父子进程间共享内存。
- 常见的信号有哪些?:SIGINT,SIGKILL(不能被捕获),SIGTERM(可以被捕获),SIGSEGV,SIGCHLD,SIGALRM
- 虚拟内存的作用?
- 虚拟内存的实现?
- 操作系统层面对内存的管理?
- 内存池的作用?STL里内存池如何实现?
- 进程空间和内核空间对内存的管理不同?
- Linux的slab层,VAM?
- 伙伴算法
- 高端内存
- Linux进程分为两种,实时进程和非实时进程;
- 优先级分为静态优先级和动态优先级,优先级的范围;
- 调度策略
- 交互进程通过平均睡眠时间而被奖励;
(1) 死锁产生的条件;
(2) 死锁的避免;
- Linux命令 在一个文件中,倒序打印第二行前100个大写字母
cat filename | head -n 2 | tail -n 1 | grep '[[:upper:]]' -o | tr -d '\n'| cut -c 1-100 | rev
- 与CPU,内存,磁盘相关的命令(top,free, df, fdisk)
- 网络相关的命令netstat,tcpdump等
- sed, awk, grep三个超强大的命名,分别用与格式化修改,统计,和正则查找
- ipcs和ipcrm命令
- 查找当前目录以及字母下以.c结尾的文件,且文件中包含”hello world”的文件的路径
- 创建定时任务
- 五种IO模型:阻塞IO,非阻塞IO,IO复用,信号驱动式IO,异步IO
- select,poll,epoll的区别
Linux的API
- fork与vfork区别
fork和vfork都用于创建子进程。但是vfork创建子进程后,父进程阻塞,直到子进程调用exit()或者excle()。
对于内核中过程fork通过调用clone函数,然后clone函数调用do_fork()。do_fork()中调用copy_process()函数先复制task_struct结构体,然后复制其他关于内存,文件,寄存器等信息。fork采用写时拷贝技术,因此子进程和父进程的页表指向相同的页框。但是vfork不需要拷贝页表,因为父进程会一直阻塞,直接使用父进程页表。
- exit()与_exit()区别
exit()清理后进入内核,_exit()直接陷入内核。
- 孤儿进程与僵死进程
- 孤儿进程是怎么产生的?
- 僵死进程是怎么产生的?
- 僵死进程的危害?
- 如何避免僵死进程的产生?
- 伙伴算法,用于管理物理内存,避免内存碎片;
- 高速缓存Slab层用于管理内核分配内存,避免碎片。
- 共享内存的实现原理?
- 系统调用与库函数(open, close, create, lseek, write, read)
- 同步方法有哪些?
- 互斥锁,自旋锁,信号量,读写锁,屏障
- 互斥锁与自旋锁的区别:互斥锁得不到资源的时候阻塞,不占用cpu资源。自旋锁得不到资源的时候,不停的查询,而然占用cpu资源。
- 死锁
其他
- ++i是否是原子操作
明显不是,++i主要有三个步骤,把数据从内存放在寄存器上,在寄存器上进行自增,把数据从寄存器拷贝会内存,每个步骤都可能被中断。
- 判断大小端
设计模式
- 单例模式线程安全的写法
- STL里的迭代器模式,适配器模式
分布式系统
- map_reduce原理 (这篇文章讲的很通俗易懂)
- 负载均衡
- CDN
主要列出考察内容的方向,问题的理解就得靠自己实践和阅读书籍了,相关问题的答案在我这篇博客中给出了自己理解的程度,欢迎交流!