我爱编程

Linux后台C++学习之路 & 面经知识点收录

2018-04-27  本文已影响1379人  75f9375f79b0

Linux后台C++学习之路 & 面经知识点收录


面经知识点收录

C++

extern "C"的作用:可以把程序编译成汇编文件,然后从汇编代码去看它的作用

C/C++ const关键字:再了解一下C++字符串常量以及普通const常量的内存布局,还有与volatile一起使用的效果,然后可以看出C里的const与C++里的const还是有一定差别的...

C/C++ static关键字:了解一下ELF(参见《深入理解计算机系统》第七章:链接),然后从符号表的角度去分析static关键字的作用,注意:C++不像python等解释性语言,它不会执行类定义的代码,所以类的静态数据成员必须在类外定义(除了静态常量),这个时候static的作用跟普通的static语义不同...还有,static函数在单例模式中有一个应用(参见《Effective C++》条款4:确定对象被使用前已先被初始化)

C/C++ volatile关键字:在底层代码中用得多(之前调试linux文件系统的时候,想要获得一个file_struct对象指针,然后这个指针总是被优化掉,不清楚是不是跟volatile有关...)

C/C++ restrict关键字:在函数库接口中用得多

C/C++内存分配管理:C++中的new只是对malloc进行了一层封装,malloc的具体实现可以看glibc的malloc源码,然后调用system call,最终会接触操作系统的内存管理模块,所以最终还是需要了解操作系统的堆管理(简单堆管理参阅《深入理解计算机系统》第九章:虚拟存储器,linux中内存管理具体实现可以阅读linux源码),需要特别了解内存池的实现(可以阅读sgi stl源码)还有伙伴系统与slab...

C++反射:工厂模式以及C++17了解一下

C++异常机制:网上有很多讲C++异常机制的博客

C++智能指针:可以按照接口要求自己实现一下四个简单的智能指针,其中share_ptr里的析构器其实是一个仿函数,然后可以自己想办法去实现一下function,any之类的模板类

C++四种类型转换:http://www.cplusplus.com/doc/tutorial/typecasting

C++ string实现原理:其实实现与vector差不多,具体实现参阅sgi stl源码

C++ map、set实现原理:封装了一颗红黑树,红黑树重要的就是旋转,还有平衡度(根据黑高证明),具体实现参阅sgi stl源码

C++函数重载、覆盖、隐藏:重载可以从汇编代码去看(根据参数类型去重命名函数名),覆盖可以去从虚函数表去分析,隐藏可以从作用域去理解

C++编译时多态与运行时多态:类的多态(运行时多态)一定要看看《深度探索C++对象模型》这本书,stack overflow上有一个帖子深度讨论了类的多态、虚继承这些,讲到了构造析构过程中vptr的变化,然后可以自己去适当理解为什么虚函数的具体调用依赖于构造析构的当前进度(链接:https://stackoverflow.com/questions/6258559/what-is-the-vtt-for-a-class. )。注意,函数模板不能局部特例化,不然就是模板重载,不得不多说一句,函数模板实例化后的函数与普通函数不在同一命名空间中(不是C++语言支持的namespace,是编译器所用的命名空间),所以能够出现具有相同名字相同参数类型的函数,实际上,从汇编代码去看,其实最终的名字还是不同的

C++为什么构造函数不能设置为虚函数:vptr还没有被设置,会出现先有鸡还是先有蛋的矛盾

new/delete和 malloc/free的区别:《Effective C++》定制new和delete(条款49~52)了解一下

如何实现只能动态分配类对象,不能静态分配:只是要求不能在栈上分配,必须在堆上分配

动态链接库与静态链接库的区别

设计模式

单例模式(static函数可以实现)

策略模式(举例:share_ptr的析构器)

简单工厂、工厂方法、抽象工厂模式

装饰模式(闭包:C++ lambda、Python decorator了解一下)

代理模式(举例:iterator有点代理模式的意思)

原型模式(举例:实现boost库中的any时需要用到的clone方法)

模板方法模式(《Effective C++》条款35:考虑virtual函数以外的其他选择 有介绍,但是举的例子感觉不是很好,感觉最大的突出点是事前和事后,之后看了《大话设计模式》对模板方法的介绍,感觉它的最大特点应该是实现最大化代码复用)

适配器模式(举例:STL中的容器适配器)

迭代器模式(举例:iterator)

数据库

数据库基本操作:可能还会要求通过sql语句对数据库进行调优

数据库索引:索引数据结构的实现,如何设置索引、以及复合索引内部的顺序(比如说,假设有一个复合主键包含A、B两列,索引AB与索引BA对数据库的影响)

数据库事务:底层如何实现事务

数据库引擎

数据库存储过程

数据库的第一二三范式

delete、truncate、drop的区别及应用场所

计算机网络

HTTP状态码

流量控制

拥塞控制:高延迟拥塞控制会降低tcp传输效率,这个时候需要自己实现拥塞控制或者避免拥塞控制,所以需要封装udp或者ip数据报(如果需要重写拥塞控制算法,可以了解一下BBR算法)

TCP连接的建立与终止:从tcp三次握手可以引入Ddos攻击

TIME_WAIT:作用以及如何避免

Ddos攻击原理:listen队列

长肥管道

7+5层模型协议、设备

简单ftp服务器socket编程:注意尽量使用一个请求一个线程/进程模型

算法

一定要把《剑指offer》刷到滚瓜烂熟,里面的算法最好能全部手写出来,一般面试的手撕算法几乎都来源于这本书

大数据处理:大数据top 100啊之类的问题很常见

大整数计算:转为字符串计算或者很强的可以自己用位运算实现一下...

如何设计好的散列函数

动态规划:了解一下动态规划基本概念以及有哪些常见算法

贪心算法:了解一下贪心算法基本概念以及有哪些常见算法

排序算法:快速排序、堆排序、归并排序、插值排序、冒泡排序、选择排序、计数排序(了解一下)、基数排序(了解一下),除了两个需要了解的,其他六个都需要快速写出来,而且知道它们的平均、最坏时间、空间复杂度

搜索算法:折半查找(一定要能快速写出来,还有其变种),二叉树查找,hash查找

数据结构-堆

数据结构-链表:数据结构-跳表、算法:二叉搜索树转为双向链表、链表回环、反转、复杂链表的复制...

数据结构-树:数据结构-AVL树、红黑树、B+树,算法:二叉树的前中后序遍历,还有《剑指offer》上的树算法

数据结构-图:dfs、bfs、dijkstra、floyd、prim、kruskal都要能够写出来

字符串算法:kmp、boyer-moore都要能够写出来、正则算法了解一下

手撕算法:手撕算法的代码量一般都不是很大,所以应该去权衡一下什么算法更容易被考到什么不容易被考到。除了《剑指offer》,还有很多跟程序鲁棒性和性能有关的手撕代码题:strcpy,实现单例模式...,还有一些题来源于leetcode,但是几乎都是easy或者medium程度的题

操作系统/Linux 内核

中断:介绍中断的作用,要是再能从硬件、汇编级别去介绍一下中断会发生什么就更棒了

信号:几乎所有讲操作系统的书都有介绍信号,linux信号参阅《Unix环境高级编程》第10章:信号,以及《深入理解linux内核》第11章:信号,需要了解可靠信号与不可靠信号的区别,还需要特别了解SIGCHLD、SIGCLD信号

进程与线程:轻量级进程、系统级线程、用户级线程、进程,这些可以读linux内核源码以及一些资料很容易理解,协程(Python中yield的效果以及它的具体实现(C源码)了解一下),可以去网上找找C++的协程库去读一读

linux常见的调度算法:知道这些算法的思想就行,读个linux源码就更棒

linux文件系统:《深入理解linux内核》第12章:虚拟文件系统 以及 第18章:Ext2和Ext3文件系统 以及 第16章:访问文件,可以让你深入了解linux文件系统

linux IPC:System V、Posix IPC熟悉一下,可以参阅《Unix环境高级编程 进程间通信》,以及清楚它们的作用与优缺点,当然还是推荐去阅读一下IPC的linux内核源码

如何实现linux的高并发,线程池的思想:github上有好多好多线程库,抓一个下来自己读一读,代码量不是很大,很推荐自己动手写一写

死锁产生的四个必要条件及如何预防

编写linux的并发测试程序:生产者消费者并发程序要求能够写得出来

惊群效应:举例子讲一下惊群现象,然后去了解一下如何避免。内核中存在两个惊群的例子,accept惊群与epoll惊群,linux内核经过改进避免了一些惊群,可以从内核源码去解释一下它是怎么做的

fork、vfork、clone的区别:这个真的只能读源码才能深入了解了,注意,phtread线程库就是使用的clone

僵尸进程:清楚一下概念以及它的危害,然后知道如何去避免僵尸进程

select、poll、epoll的区别:从内核源码去分析,select与poll实现差不多,读了一个源码差不多很快就能读懂第二个,epoll设计很独特也很有意思,赶快去读一读

linux内核伙伴系统、slab缓存(实现原理、与普通内存分配的区别以及优势):简单介绍参阅《深入理解linux内核》第8章:内存管理,深入了解就去读linux内核源码...


学习方法

收到好几条私信评论,问我学习方法,知道自己很菜,虽然有时候会盲目自信,但是跟一些大牛比起来还是会深深感到自卑...没了解学习过一个领域,看到别人在这方面有见解,然后就会觉得别人特别牛,可是一旦了解,就会发现并没有想象中的那么厉害,所以说我真的很菜的(并没有装逼,是真心话)...

适合一个人的学习方法,不一定适合另一个人,所以在这发表的见解,大家取其精华去其糟粕...

有好几个非cs专业的同学问我学习方法,那么先贴一个链接:http://study.163.com/curricula/cs/grade-1.htm. ,这里有cs专业大一到大四开的所有课程,可能这里有些课程质量不是很好,但是还是可以了解一下具体开过哪些课,然后自己去找教程去认真学习。这些课程中开的数据结构课感觉还不错,可以去认真看看...

看到好几个同学说,问别人学习方法都是推荐了一大堆书,哪看的完...其实很多东西只有看书才能看得明白的也能看得更透彻,我几乎都是看书看源码,遇到一些很难的就google或者找视频看...因为如果所有东西都看别人讲(google看博客或者看视频),就可能遇到一个知识点不同的人不同的看法,然后自己就弄弄不明白还会被带歪然后就心情爆炸...所以我还是会推荐大家看书或者看源码,但是会讲重点哪些地方应该看哪些地方简单了解一下,这样对大家的时间还是能省一点的...

大家一定要有明确的目标,知道自己该学些什么又有哪些东西学了对主线没有帮助的,目的明确一点真的很重要,我明知我是linux后台C++,以前还花了很长时间去学习windows下的编程,虽然学习了一点东西,但是对我的发展并没有多大帮助而且真的很浪费时间,因为我把它当成主线来认真学习了...就算是这样,以后还是接触linux,windows用得少了也很快就会忘记,所以希望大家能好好权衡...

我很强调动手以及发散思维,发散思维比如说学到一个东西能很快联想到之前学过的另一个东西,以及遇到新的东西希望能够从更底层去猜测它的实现,要是等以后再接触到它的实现的时候,可以将具体实现与之前自己的猜测进行比较...动手是真的巨重要,我讨厌伸手党,也讨厌纸上谈兵,遇到问题我会尽量去用代码或者实现源码去解决问题,有时候跟踪程序的具体过程可能还要反汇编,有时候遇到很难很难的调试问题,比如说之前调试linux文件系统,我真的花了巨长巨长的时间,这个时候需要很强的耐心还有明确的目的,因为有时候调试着调试着突然忘记了自己想要干吗...

我从很早开始使用linux作为自己的日常工作环境,为了学习《Unix环境高级编程》,我几乎尝试了所有linux发行版还有其他unix系统(这些作为虚拟机部署),部署其实也是一件很有趣的事,也能让你更加深入的了解类unix系统...推荐大家使用linux作为自己的学习环境,而且还能克制自己玩大部分游戏...

ok,开始吧...

C++语言

在学习C++之前,我只有C基础。我是啃《C++ Primer》这本书,当时是第五版,那个时候最新的还是C++11标准,也推荐大家看这本书,因为C++14、17都还是太新,用的很少,而且大多公司也才从C++98过渡到C++11。这本书我读了很多遍,重点是STL与类,模板编程与OO几乎都占了C++的半壁江山。关于C++面向对象,读《C++ Primer》这本书关于类的讲解还有《深度探索C++对象模型》,然后这部分内容就差不多了。把细节列出来吧:拷贝控制(默认构造、值构造、拷贝构造、移动构造、拷贝复制、移动复制、析构)这些需要很熟练很熟练的了解,这其中初值列与隐含的析构列很重要,对象模型(简单继承、含有虚函数的继承、含有虚基类的继承)它们的内存布局需要很清楚的知道,还有看上面那个stack overflow的帖子...命名返回值优化顺便了解一下(见《深度探索C++对象模型》),然后就能理解为什么有时候类实例的创建没有按照正确流程...模板编程首先我推荐一定要把SGI STL库源码阅读一遍,就算源码没有看过,STL还是得会熟练的使用,重点在set/map、string/vector,要是能自己写一写就最好了,很喜欢侯捷先生的两句话:“源码之下,了无秘密”,“天下大事,必作于细”。内存分配器、几个容器、几个容器适配器、几个范型算法,代码量大约在1~2w行左右,然后可以自己再实现更多的东西,例如可以再实现一些boost库中的东西、四个智能指针、any、tuple之类的,然后能真正让你体会到模板元编程的乐趣...模板编程几个重要细节列出来:函数模板--显式实例化、特例化,类模板--显式实例化、全特化、局部特例化,模板容易出现的问题见《Effective C++》条款43:学习处理模板化基类内的名称以及条款46:需要类型转换时请为模板定义非成员函数,可能会帮到你。还有一个很容易出现的问题应该就是关于模板的链接错误了(提示没有找到指定的函数),其实就是没有模板实例化,具体问题去google...C++11还有很多特性,右值呀、lambda呀、function呀,RTTI呀...右值可以从汇编角度去看;lambda也可以从汇编角度去看,lambda其实就是个闭包,在C++中lambda没有一个具体的类型,将一个捕获列表与一个函数捆绑在了一起,所以从汇编去看的话,返回一个lambda其实就是返回捕获列表中捕获的数据;function运用了类型擦除,具体实现可以google,其实boost库中的any也用了类型擦除,RTTI的话其实读完《深度探索C++对象模型》,从虚函数表中应该已经知道了它的原理;还有一些高级部分:类型萃取呀、tuple呀这些...,类型萃取读完SGI STL源码之后应该已经能够深刻的理解了,tuple的话就是用了模板递归这些嘛,一些模板元编程...书籍推荐:《C++ Primer》、《深度探索C++对象模型》、《STL源码剖析》、《C++标准程序库》(参阅)、《Boost程序库完全开发指南》(简单读一读)、《Effective C++》(想要更好的学习C++强烈推荐)、《More Effective Modern C++》(让你更好的了解C++11,但是这本书目前还没有中文版,但是感兴趣的同学可以啃一啃...)

设计模式

推荐阅读《大话设计模式》,提醒一下,设计模式面试考得不多,但是想要了解的话还是去看一看...其中好几个设计模式可以联系已学过的东西加深印象,学习设计模式最好最快的办法就是理解它的UML图...

数据库

我的数据库不是很好,快速、基本地学习数据库推荐阅读《Sql必知必会》(很薄的一本书)

计算机网络

《Tcp/ip详解》(卷一)了解一下,看上面收录的面试知识点,着重去学习重要的那些。详细介绍tcp可以阅读《计算机网络》(谢希仁)(对也就是大多学校发的那本教材)第7章:运输层,其中的tcp可靠传输相关的一定要认真认真读!!,列出细节吧:滑动窗口、拥塞控制、还有状态图、还有TIME_WAIT(重中之重),socket编程可以阅读《Unix网络编程 套接字联网API》,其中跟SCTP相关的可以忽略掉,其实再省略一点的话只读第一二部分就行了...

算法

上面收录的面试知识点基本已经全部讲了,也就是面试的时候所有数据结构与算法都可能会考到。我算法还是有点薄弱,因为花了太多的时间去学习专业课然后没有太多的时间去刷题,但是强烈建议大家多去刷刷题,ACM尽量参加,含金量特别特别高。leetcode、牛客算法都该做做,尤其是牛客上关于《剑指offer》的专题一定要全部刷到滚瓜烂熟...刚刷算法可能会很困难,但是坚持去做,做完去看看题解还是会很有进步的。上面我还给了网易云课堂的链接,里面有开数据结构的课,学习基础可以去看看...推荐书籍《Algorithms 4th Edition》(英文版,所以可能有点难读,英语不是很好的话就参阅),《算法导论》

操作系统

还是上面给的网易云课堂链接,里面有一门操作系统的课,简单学习的话可以去看看。

linux内核

先简单读一遍《Linux内核设计与实现》,偶尔可对照一下linux内核源码。但是呢,这本书其中感觉有很多错误,不是很严谨,所以不推荐作为深入学习linux内核的书籍,只是作为简单的入门。深入学习linux内核的话,可以认真读linux内核源码然后对照《深入理解linux内核》这本书,当然,重点还是读源码...读了《Linux内核设计与实现》之后已经有了基础了,然后其实已经可以有能力自己读懂源码了...可能会觉得还是有困难,讲一下我的linux入门之路吧...我先读了一遍《Linux内核设计与实现》,当时对照着源码读的,当然啦,书上不可能所有东西都讲,只是挑一些特别重要的讲,其他的还是需要自己去看去理解...读完这本书之后,大致的内存管理、进程控制之类的还是了解了,我真正入门是在读多路复用select、poll、epoll源码的时候,这三个函数源码真的很简单,读懂之后能很有效地增强自信心,然后就觉得很有趣,然后就开始了真正的linux学习之路。之后慢慢地linux文件系统、内存管理、IPC之类的都能看懂,不懂google,看博客,然后继续读...linux内核源码其实并没有特别难学习,难的是不知道怎么入门...这里有奥特曼的epoll源码总结:https://www.nowcoder.com/discuss/26226. ,之后要是有时间我再把我对do_fork、select、poll、epoll、ipc、文件系统、内存管理、大多数系统调用、进程调度呀之类的源码总结贴出来...

汇编

对了,走C++后台这条路,就是需要与底层进行接触,所以了解汇编是必不可少的。尽早学会汇编,对以后学习任何高级语言、操作系统都会很有帮助。推荐阅读《汇编语言》(王爽),《X86汇编语言 从实模式到保护模式》,《汇编语言程序设计》(简单阅读一下,了解AT&T汇编格式)

帖子内容没用md把格式做好,所以将就读一读吧...虽然很菜,但是还是希望上面的总结能够帮助到大家...有什么学习相关的问题可以私信我或者给我评论...

面经已发布:https://www.nowcoder.com/discuss/77507.
原文链接:https://www.jianshu.com/p/3427b2bee081.

上一篇下一篇

猜你喜欢

热点阅读