百度面试
1、为什么不把函数实现放在头文件里面?
头文件一般存放是类、变量、函数的声明,一般不会存放它们的定义,防止的就是重复编译、重定义。因为源文件用#include指令引用头文件,其实是一个简单的复制粘贴,也就是把头文件内容复制到源文件中#include那一行。如果把定义放在头文件里,且多处引用的话,同一个函数就会被多个源文件重复编译,就会有编译错误了。
还有就是为了类的封装型考虑,提供一个接口,把函数定义编译成目标代码,把目标代码和头文件提供给使用者,使用者通过包含头文件来调用目标代码中的函数。实现和接口分离
2、inline函数为什么高效?
3、OSI的7层
4、TCP/IP的模型 4层
5、TCP 和 UDP 的区别
6、问I/O复用,问epoll为什么高效?
7、问了加锁,问 IPC
8、操作系统如何从死循环中夺回CPU的使用权?
提高优先级、阻塞原语、杀死进程
9、操作系统的时钟计时器的计时准不准确,如果不准确是什么原因?
10、问我 stack 有什么应用场景。
递归函数参数开辟空间、类创建和析构顺序、数制转换、括号匹配检验、迷宫求解、表达式求值
11、二叉平衡树有什么应用场景
快速查找、红黑树
12、memcpy编程
13、一个是 1024!末尾有多少个 0 编程
末尾0的个数取决于乘法中因子2和5的个数。显然乘法中因子2的个数大于5的个数,所以我们只需统计因子5的个数。
是5的倍数的数有: 1024 / 5 = 204个
是25的倍数的数有:1024 / 25 = 40个
是125的倍数的数有:1024 / 125 = 8个
是625的倍数的数有:1024 / 625 = 1个
所以1024! 中总共有204+40+8+1=253个因子5。
也就是说1024! 末尾有253个0。
14、给我一个中序遍历和一个后续遍历,让我画出二叉树的结构,写出前序遍历。
15、哪些常用的 linux 系统调用?
我说有 open,write,read,fork,getpid获取进程标识号,getppid,获取父进程标识号,wait,soket、listen、accept、connect等等
16、 n 条直线能把一个平面分成多少个区域?
直线数量 1 2 3 4 ….n
把平面分
成的块数 2 4 7 11
1+1 1+1+2 1+1+2+3 1+1+2+3+4 1+1+2+3+4+ …+n
1+1+2+3+4+ …+n=1+(1+n)n/2
17、#include和#import “” <>和@class区别讲解
区分#include
#include <xxx.h>:它用于对系统自带的头文件的引用,编译器会在系统文件目录下去查找该文件。
#include "xxx.h":用户自定义的文件用双引号引用,编译器首先会在用户目录下查找,然后到安装目录中查找,最后在系统文件中查找。
在使用#include的时候要注意处理重复引用(这也是objc中#include与#import的区别)
例如:ClassA与ClassB同时引用了ClassC,不做重复引用处理的时候在ClassD中同时引用ClassA,ClassB编译会提示对ClassC重复引用的错误。
我们可以:
#ifndef _CLASSC_H
#define _CLASSC_H
#include "ClassC"
#endif //这样处理在编译时就不会有重复引用的错误出现(在objc中#import解决了这个问题,这是它们的区别)#import
#import //大部分功能和#include是一样的,但是他处理了重复引用的问题,我们在引用文件的时候不用再去自己进行重复引用处理。
@class主要是用于声明一个类,告诉编译器它后面的名字是一个类的名字,而这个类的定义实现是暂时不用知道的,后面会告诉你。也是因为在@class仅仅只是声明一个类,所以在后面的实现文件里面是需要去#import这个类,这时候才包含了这个被引用的类的所有信息。