linux和os:
netstat :显示网络状态
tcpdump:主要是截获通过本机网络接口的数据,用以分析。能够截获当前所有通过本机网卡的数据包。它拥有灵活的过滤机制,可以确保得到想要的数据。
ipcs:检查系统上共享内存的分配
ipcrm:手动解除系统上共享内存的分配
awk sed
共享内存的使用实现原理
(必考必问,然后共享内存段被映射进进程空间之后,存在于进程空间的什么位置?共享内存段最大限制是多少?)
默认32M
kern.ipc.shmmax
cd /proc/sys/kernel
vi shmmax
共享内存的原理:同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。
c++进程内存空间分布
(注意各部分的内存地址谁高谁低,注意栈从高到低分配,堆从低到高分配)
1栈,局部变量、函数参数等。
2. 堆,new分配的内存块,delete。如果程序员没有释放掉,程序结束后,操作系统会自动回收。
3.自由存储区,malloc等分配的内存块,和堆是十分相似的,用free来结束自己的生命的。
4.全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
5.常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)
ELF是什么?其大小与程序中全局变量的是否初始化有什么关系(注意未初始化的数据放在bss段)
二进制、可执行、目标代码、共享库和核心转储的标准文件格式
可执行文件:包含了代码和数据。具有可执行的程序。
可重定位文件:包含了代码和数据(这些数据是和其他重定位文件和共享的
object文件一起连接时使用的)
共享object文件(又可叫做共享库):包含了代码和数据(这些数据是在连接
时候被连接器ld和运行时动态连接器使用的)。
使创建共享库容易,使动态装载和共享库的结合更加容易。在ELF下,在C++
中,全局的构造函数和析构函数在共享库和静态库中用同样方法处理。
进程间通讯同步机制,并详细说明
信号,信号量、管道,匿名管道,共享内存,套接字
linux命名管道的原理
由于基于fork机制,所以管道只能用于父进程和子进程之间,或者拥有相同祖先的两个子进程之间 (有亲缘关系的进程之间)。为了解决这一问题,Linux提供了FIFO方式连接进程。FIFO又叫做命名管道(named PIPE)。
FIFO (First in, First out)为一种特殊的文件类型,它在文件系统中有对应的路径。当一个进程以读(r)的方式打开该文件,而另一个进程以写(w)的方式打开该文件,那么内核就会在这两个进程之间建立管道,所以FIFO实际上也由内核管理,不与硬盘打交道。之所以叫FIFO,是因为管道本质上是一个先进先出的队列数据结构,最早放入的数据被最先读出来,从而保证信息交流的顺序。
线程同步
条件变量 互斥锁 信号量机制
linux的如何实现1G映射到4G
虚拟存储技术,局部性原理
makefile编写,虽然比较基础,但是会被问到
mkdir mf
cd mf
vim makefile
hello.o:hello.c hello.h
gcc –c hello.o -Lm
make
./hello
1 目标可以是一个或多个,可以是Object File,也可以是执行文件
2 需要的条件就是生成目标所需要的文件或目标
3 命令就是生成目标所需要执行的脚本
gdb调试相关的经验,会被问到
如何定位内存泄露?
New完没有delete, malloc没有free
动态链接和静态链接的区别
动态链接指生成可执行文件不将所有程序用的函数链接到一个文件,程序运行时操作系统的动态链接库找
静态链接就是把所有用到的函数全部链接到可执行文件中。
32位系统一个进程最多有多少堆内存
多线程和多进程的区别
对比维度 | 多进程 | 多线程 | 总结 |
数据共享、同步 | 数据共享复杂,需要用IPC;数据是分开的,同步简单 | 因为共享进程数据,数据共享简单,同步复杂 | 各有优势 |
内存、CPU | 占内存多,切换复杂,CPU利用率低 | 占内存少,切换简单,CPU利率高 | 线程优 |
建销毁、切换 | 创建销毁、切换复杂,速度慢 | 创建销毁、切换简单,速度很快 | 线程优 |
编程调试 | 编程简单,调试简单 | 编程复杂,调试复杂 | 进程优 |
可靠性 | 进程间不会互相影响 | 一个线程挂掉将致整个进程挂掉 | 进程优 |
分布式 | 适应于多核、多机分布式;如果一台机器不够,扩展到多台机器比较简单 | 适应于多核分布式 | 进程优 |
线程私有的 栈 程序计数器 寄存器
写一个c程序辨别系统是16位or32位
int k=~0;
if((unsigned int)k >63356) cout<<"at least 32 bits"<
else cout<<"16 bits"<
写一个c程序辨别系统是大端or小端字节序
用联合体:如char类型的,可以看他输出的是int的高字节还是低字节
信号:列出常见的信号,信号怎么处理?
kill -l
信号集及信号集操作
sigfillset(sigset_t *set); 设置所有的信号到set信号集中;
sigemptyset(sigset_t *set); 从set信号集中清空所有信号;
sigaddset(sigset_t *set,int sig);在set信号集中加入sig信号;
sigdelset(sigset_t *set,int sig);在set信号集中删除sig信号;
阻塞信号相关函数
int sigprocmask(int how,const sigset_t *set,sigset_t *set); 根据how值,设置阻塞信号集,或释放阻塞的信号集
int sigpending(sigset_t *set); 获取在阻塞中的所有信号;
int sigsuspend(const sigset_t *set); 类似于 pause()函数!
i++是否原子操作?并解释为什么?
不是 内存到寄存器、寄存器自增、写回内存;三个阶段中间都可以被中断分离开.
什么是死锁?如何避免死锁(每个技术面试官必问)
死锁的条件。
(互斥条件(Mutual exclusion):
1、资源不能被共享,只能由一个进程使用。
2、请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
3、非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
4、循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。
处理死锁的策略:
1.忽略该问题。
2.检测死锁并且恢复。
3.仔细地对资源进行动态分配,以避免死锁。
4.通过破除死锁四个必要条件之一,来防止死锁产生。)
列举说明linux系统的各类异步机制
磁盘IO
同步就是你叫我去吃饭,我听到了就和你去吃饭;如果没有听到,你就不停的叫,直到我告诉你听到了,才一起去吃饭。
异步就是你叫我,然后自己去吃饭,我得到消息后可能立即走,也可能等到下班才去吃饭。
1、tcp和udp区别
Tcp提供可靠数据传输,UDP不
TCP 有确认、序列号、超时重传
2、tcp如何实现流量控制
利用滑动窗口机制,
设A向B发送数据。在连接建立时,B告诉了A:“我的接收窗口是 rwnd = 400 ”
5、c++多态、多态的实现原理(虚函数)
C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。
6、如何实现手机通讯录的查找时候的提示功能
TextWatcher 监听字母变化后 动态改变 listview
B-树
是一种多路搜索树(并不是二叉的):
1.定义任意非叶子结点最多只有M个儿子;且M>2;
2.根结点的儿子数为[2, M];
3.除根结点以外的非叶子结点的儿子数为[M/2, M];
4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
5.非叶子结点的关键字个数=指向儿子的指针个数-1;
6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
8.所有叶子结点位于同一层;
7、B+树
B+树是B-树的变体,也是一种多路搜索树:
1.其定义基本与B-树同,除了:
2.非叶子结点的子树指针与关键字个数相同;
3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);
5.为所有叶子结点增加一个链指针;
6.所有关键字都在叶子结点出现;
8、hash表
a、如果让我实现hashtable,需要考虑什么
如何解决冲突
b、解决冲突的方法,原理,应用场景
10、mysql的引擎
mysql> show engines
11、如果从查询等层面,MyIsam和InnoDB的区别
ISAM和MyISAM引擎不支持事务处理(transaction process)也不支持外来键。
尽管要比ISAM和 MyISAM引擎慢很多,但是InnoDB对事务处理和外来键支持
MyISAM适合:(1)做很多count 的计算;(2)插入不频繁,查询非常频繁;(3)没有事务。
InnoDB适合:(1)可靠性要求比较高,或者要求事务;(2)表更新和查询都相当的频繁,并且表锁定的机会比较大的情况
linux分析apache日志获取最多访问的前10个IP
awk '{a[$1] += 1;} END {for (i in a) printf("%d %s\n", a[i], i);}' 日志文件 | sort -n | tail
const的含义及实现机制,比如:const int i,是怎么做到i只可读的?
编译器相关,优化时直接代替为常量
valitale的含义
告诉编译器此处必须得从地址去取,不得作相关优化
OFFSETOF(s, m)的宏定义,s是结构类型,m是s的成员,求m在s中的偏移量
#define OFFSETOF(s, m) ({s s1;(void*)(&s1)-(void*)(&s1->m);})
设计一个洗牌的算法,并说出算法的时间复杂度
日志里面有ip,如何统计出日志中出现最多的10个ip···top k问题
一定要对自己的项目非常熟悉:比如遇到的问题、解决的思路、瓶颈、架构的优化、细节的优化等等
最后:补充一个最最重要,最最坑爹,最最有难度的一个题目:一个每秒百万级访问量的互联网服务器,每个访问都有数据计算和I/O操作,如果让你设计,你怎么设计?