百度面试
C++面试题整理3
百度一面 50分钟
1. strcpy和memcpy的区别
(1)用途上的不同,strcpy只拷贝字符串,并且会是拷贝到字符串的最后一个’\0’结束符结束。而memcpy可以拷贝任意类型的数据,只要指定要拷贝的字节数。因此需要在使用时指定字节数n。参数以及返回值为void指针,
(2)用法上的不同,strcpy不需要指定长度。
也因此,strcpy没有memcpy安全。
2. 手写memcpy
我觉得memcpy就是实现了内存覆盖安全!!!
而strcpy函数应当是调用memcpy来实现的。因此对于字符串地址有覆盖的情况也能正确处理!!!
3. linux下的malloc和free底层都干了什么事(调用free貌似系统不一定会真正释放内存)
malloc:
malloc 是 glibc 中内存分配函数,也是最常用的动态内存分配函数,其内存必须通过 free 进行释放,否则导致内存泄露。
关于 malloc 获得虚存空间的实现,与 glibc的版本有关,但大体逻辑是:
1. 若分配内存小于 128k ,调用 sbrk() ,将堆顶指针向高地址移动,获得新的虚存空间。
2. 若分配内存大于 128k ,调用 mmap() ,在文件映射区域中分配匿名虚存空间。
3. 这里讨论的是简单情况,如果涉及并发可能会复杂一些,不过先不讨论。
其中 sbrk 就是修改栈顶指针位置,而 mmap 可用于生成文件的映射以及匿名页面的内存,这里指的是匿名页面。
而这个 128k ,是 glibc 的默认配置,可通过函数 mallopt 来设置。
free:
malloc 使用 mmap 分配的内存 ( 大于 128k) , free 会调用 munmap 系统调用马上还给 OS ,实现真正释放。
堆内的内存,只有释放堆顶的空间,同时堆顶总连续空闲空间大于 128k 才使用 sbrk(-SIZE) 回收内存,真正归还 OS 。
堆内的空闲空间,是不会归还给 OS 的。
4. 手写一个类(考察类的前置声明)
【稍微注意一下类的前置声明以及头文件包含的区别】
究竟什么时候需要前置声明,什么时候需要头文件包含呢?
头文件包含其实是一想很烦琐的工作,不但我们看着累,编译器编译的时候也很累,再加上头文件中常常出现的宏定义。感觉各种宏定义的展开是非常耗时间的,远不如自定义函数来得速度。我仅就不同头文件、源文件间的句则结构问题提出两点原则,仅供参考:
第一个原则应该是,如果可以不包含头文件,那就不要包含了。这时候前置声明可以解决问题。如果使用的仅仅是一个类的指针,没有使用这个类的具体对象(非指针),也没有访问到类的具体成员,那么前置声明就可以了。因为指针这一数据类型的大小是特定的,编译器可以获知。
第二个原则应该是,尽量在CPP文件中包含头文件,而非在头文件中。假设类A的一个成员是是一个指向类B的指针,在类A的头文件中使用了类B的前置声明并编译成功,那么在A的实现中我们需要访问B的具体成员,因此需要包含头文件,那么我们应该在类A的实现部分(CPP文件)包含类B的头文件而非在声明部分(H文件)包含。
如果使用object reference 或 object point 可以完成任务,就不要用object
这样可以尽最大可能避免#include
为声明式和定义式提供不同的头文件
5. epoll和select的区别
6. map遍历删除(考虑迭代器失效)
c++容器的元素删除两个原则:
1) 如果容器是标准序列容器,写一个循环来遍历容器元素,每当调用erase时记得都用它的返回值更新你的迭代器。
2) 如果容器是标准关联容器,写一个循环来遍历容器元素,当把迭代器传给erase时记得后置递增它(例子同上) 。
也就是说,map之类的容器并不需要考虑迭代器失效,只有vector、deque之类的连续空间的迭代器才需要考虑。
(1)vector的删除
vector <int>::iterator iter=vecInt.begin();
for ( ;iter!=vecInt.end();)
{
iter=vecInt.erase(iter);
}
j= vecInt.capacity(); //j=512
i = vecInt.size(); //i=0
【最好的立即删除所有的vector并且不会遗留capacity空间的方式是vector<int>().swap(vecInt)】
(2)map的删除
for(map<int,int>::iterator it = m.begin(); it!=m.end(); it++){
m.erase(it->first);
}
7. 手写快排
【第二篇】
1. 单链表反转,复杂链表复制
2. time_wait状态。Syn_flood攻击,time_wait状态会带来什么问题。
3. Explict关键字的作用
避免隐式类型转换。C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式).
在大部分情况中,隐式转换却容易导致错误(不是语法错误,编译器不会报错)。隐式转换总是在我们没有察觉的情况下悄悄发生,除非有心所为,隐式转换常常是我们所不希望发生的。通过将构造函数声明为explicit(显式)的方式可以抑制隐式转换。也就是说,explicit构造函数必须显式调用。
4. 为啥虚函数要定义成virtual的
5. 三次握手过程,为啥要三次握手
6. 大文件中找重复记录次数最多的记录
7. 链表的回文判断(链表每个节点存一个字符,判断该链表所有结点组成的字符串是不是回文字符串)
8. C++智能指针循环引用
class Child;
class Parent{
public:
shared_ptr<Child> child;
}
class Child{
public:
shared_ptr<Parent> parent;
}
int main(int argc, const char * argv[]) {
shared_ptr<Child> child(new Child);
shared_ptr<Parent> parent(new Parent);
child->parent = parent;
parent->child = child;
return 0;
}
9. 线程池的原理
【第三篇】
1. 进程调度算法,时间片轮转的时间片是怎么计时的?
先进先出,最短作业优先,最高响应比优先,时间片轮转,多级反馈队列
多级反馈队列调度算法描述:
1、进程在进入待调度的队列等待时,首先进入优先级最高的Q1等待。
2、首先调度优先级高的队列中的进程。若高优先级中队列中已没有调度的进程,则调度次优先级队列中的进程。例如:Q1,Q2,Q3三个队列,只有在Q1中没有进程等待时才去调度Q2,同理,只有Q1,Q2都为空时才会去调度Q3。
3、对于同一个队列中的各个进程,按照时间片轮转法调度。比如Q1队列的时间片为N,那么Q1中的作业在经历了N个时间片后若还没有完成,则进入Q2队列等待,若Q2的时间片用完后作业还不能完成,一直进入下一级队列,直至完成。
4、在低优先级的队列中的进程在运行时,又有新到达的作业,那么在运行完这个时间片后,CPU马上分配给新到达的作业(抢占式)。
在多级反馈队列调度算法中,如果规定第一个队列的时间片略大于多数人机交互所需之处理时间时,便能够较好的满足各种类型用户的需要。
2. 内存比硬盘快多少倍?
要赶紧再看一遍的:
1. ARP协议(具体,详尽)
用ping说明ARP工作的原理
假设我们的计算机IP地址是192.168.1.1,要执行这个命令:ping192.168.1.2。该命令会通过ICMP协议发送ICMP(以太网控制报文协议)数据包
该过程需要经过下面的步骤:
1. 应用程序构造数据包,该示例是产生ICMP包,被提交给内核(网络驱动程序);
2. 内核检查是否能够转化该IP地址为MAC地址,也就是在本地的ARP缓存中查看IP-MAC对应表;
3. 如果存在该IP-MAC对应关系,那么跳到步骤<7;
如果不存在该IP-MAC对应关系,那么接续下面的步骤;
4. 内核进行ARP广播,目的MAC地址是FF-FF-FF-FF-FF-FF,ARP命令类型为REQUEST(1),其中包含有自己的MAC地址;
5. 当192.168.1.2主机接收到该ARP请求后,就发送一个ARP的REPLY(2)命令,其中包含自己的MAC地址;
6. 本地获得192.168.1.2主机的IP-MAC地址对应关系,并保存到ARP缓存中;
7. 内核将把IP转化为MAC地址,然后封装在以太网头结构中,再把数据发送出去;
2. url解析,
3. OSI七层,每一层作用(为什么TCP比OSI用得广泛?)
个人简单归纳为四点:糟糕的提出者,糟糕的技术,糟糕的实现,糟糕的政策
1. 糟糕的提出者:OSI是学者们提出的(面向技术,这也意味着它很复杂,很难应用到实际),TCP则是各大计算机寡头提出(面向实用,简化了很多,直接得到了大量用户群)
2. 糟糕的技术:不知道你有没有发现,OSI中的会话和表示层几乎是空的,而数据链路和网络层有包含了太多的东西。它所制定的标准和协议都极其复杂,(据说打印出来能堆1米多)且很多功能重复(如流控和差错控制)
3. 糟糕的实现:TCP/IP协议族早期是作为UNIX的一部分,运行非常好,而且是免费的,这使它迅速在程序员中形成了一个庞大的用户群。而OSI则一直躺在实验室,没接触到群众。
4. 糟糕的政策:当初的学术界都认为OSI由美国军方背景,是美国政府的产物;而TCP是UNIX一部分,这使得很多崇尚自由的欧美程序员彻底爱上了TCP。
共同点:
1.0 两者都以协议栈的概念为基础,并且协议中的协议彼此独立.
2.0 两个模型中的各个层的功能也大体相似.
3.0 两个模型传输层之上的各层也都是传输服务的用户,并且用户是面向应用的用户.
不同点:
1.0 对于OSI/RM模型有三个明确的核心概念.(1)服务,(2)接口,(3)协议.而TCP/IP对此没有明确的区分.
2.0 OSI/RM模型是在协议发明之前设计的.而TCP/IP是在协议出现之后设计的.
3.0 一个更在的区别在于OSI/RM模型有7层.而TCP/IP只有4层.
4.0 OSI/RM的网络层同时支持无连接和面向连接的通信,但是在传输层上只支持面向连接的通信,
而TCP/IP模型的网络层上只有一种无连接通信模式,但是在传输层上同时支持两种通信模式.
4. redis高可用怎么实现的
5. redis怎么进行主从复制的,数据是怎么在集群里存储的,怎么解决高可用问题
【整理关于Redis高可用的演化】
1. 主从Redis
主从redis实际上是一种主备模式,即主redis宕机后,可以切换从redis继续提供服务。
缺点:
1.人为关注Master是否宕机
2.无法完成自动切换主从
3.从节点的功能未被充分利用
2. sentinel
为了解决上述确定,Redis官方提供了sentinel,保证redis的高可用性
图1展示的是sentinel与redis的关系,即sentinel系统对每个redis实例(主、从)均创建两个链接:命令连接、订阅连接
命令连接:发送INFO命令,与redis保持通信
订阅连接:通过订阅连接,自动发现其他sentinel实例
图2展示一个最小规模的sentinel,即至少由三个sentinel实例组成,当被监视的redis被判断为主管下线时,需要从sentinel中选举零头sentinel来进行主从切换
优点:
1.sentienl可以监控主从节点的健康状况,降低了人为监控成本
2.sentinel可以完成主从切换
缺点:
1.从节点依然未被充分利用
2.无法做到横向扩展,提供服务器的只有一个master
3. 分片
分片思想主要是利用一致性哈希算法,完成redis的横向扩展
1.通过zookeeper存储sentinel的配置信息
2.在客户端实现一致性哈希算法,通过路由算法决定redis命令由那个redis实例进行执行
3.通过增加shard,来分担单个shard的压力
缺点:
1.扩容时涉及到数据迁移,如果redis中只是缓存数据则方便处理,但如果有业务数据强依赖redis,则迁移时只能停机处理
2.无法解决冷热数据问题
6. 介绍一下redis{数据结构,底层实现,指令,分布式处理,链式结构,} 说道跳表的时候
7. 问项目 说到redis哪些方面用的缓存;缓存和数据库如何同步。
8. NIO和AIO
同步非阻塞IO和异步非阻塞IO。
NIO
NIO本身是基于事件驱动思想来完成的,其主要想解决的是BIO的大并发问题: 在使用同步I/O的网络应用中,如果要同时处理多个客户端请求,或是在客户端要同时和多个服务器进行通讯,就必须使用多线程来处理。也就是说,将每一个客户端请求分配给一个线程来单独处理。这样做虽然可以达到我们的要求,但同时又会带来另外一个问题。由于每创建一个线程,就要为这个线程分配一定的内存空间(也叫工作存储器),而且操作系统本身也对线程的总数有一定的限制。如果客户端的请求过多,服务端程序可能会因为不堪重负而拒绝客户端的请求,甚至服务器可能会因此而瘫痪。
NIO基于Reactor,当socket有流可读或可写入socket时,操作系统会相应的通知引用程序进行处理,应用再将流读取到缓冲区或写入操作系统。 也就是说,这个时候,已经不是一个连接就要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的。
BIO与NIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程。
NIO的最重要的地方是当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器上面,所以所有的连接只需要一个线程就可以搞定,当这个线程中的多路复用器进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。
AIO
9. git使用,我把命令和工作原理都说了一遍,然后每个命令做什么用的
10. c和cpp里面线程同步的函数接口
11. 共享数据同步有哪些方式【应当就是线程同步的方式吧】
12. 锁有哪几种锁?自旋锁怎么实现的?
读写锁,互斥锁,自旋锁
13. 二叉树后序遍历实现
14. 斐波那契数列分析复杂度
f(n)+xf(n-1) = y(f(n-1)+xf(n-2))
15. main函数执行之前与执行之后
其实程序运行到main函数之前做了很多工作:
操作系统装载程序之后,首先运行的代码并不是main的第一行,而是某些特别的代码,这些代码准备好main函数执行说需要的环境,并且负责调用main函数,这时候你才可以再main函数里放心大胆的写各种代码:申请内存、使用系统调用、触发异常、访问IO。在main函数返回之后,他会记录main函数的返回值,调用atexit注册的函数,然后结束进程。
如何做到Main函数之前或main之后执行代呢,其实上面引用已经提到部分,使用全局变量和atexit函数。
16. 异常,运行异常和编译异常的区别,本质原因是什么
linux下的异常机制有中断,陷入,故障和终止。
17. linux命令 :sed awk head 怎么用
more功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上。 more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还有搜寻字串的功能 。more命令从前向后读取文件,因此在启动时就加载整个文件。
less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大。less 的用法比起 more 更加的有弹性。 在 more 的时候,我们并没有办法向前面翻, 只能往后面看,但若使用了 less 时,就可以使用 [pageup] [pagedown] 等按 键的功能来往前往后翻看文件,更容易用来查看一个文件的内容!除此之外,在 less 里头可以拥有更多的搜索功能,不止可以向下搜,也可以向上搜。
可以通过head命令查看具体文件最初的几行内容,该命令默认是前10行内容,如果你想查看前面更多内容,你可以通过一个数字选项来设置,例如
head -20 install.log
STL的东西,有哪些有序的数据结构,底层是如何实现的。
聊了项目
nginx的负载均衡方式,上传文件的大小限制
静态变量和全局变量的分配方式和使用区别
野指针,智能指针,unique_ptr和shared_ptr的区别
如何追内存泄漏
多线程编程的互斥和同步
如何计算多线程server的并发
strcpy的实现和注意事项
gdb的底层实现原理
gdb调试不管是本地调试还是远程调试,都是基于ptrace系统调用来实现的。ptrace系统调用提供了一种方法,让父进程可以观察和控制其它进程的执行,检查和改变其核心映像及寄存器。主要用来实现断点调试和系统调用跟踪。
long ptrace(enum __ptrace_request request, \
pid_t pid,void *addr,void *data);
request参数的主要选项:
PTRACE_TRACEME:由子进程调用,表示本进程将被其父进程跟踪,交付给这个进程的所有信号,即使信号是忽略处理的(除SIGKILL之外),都将使其停止,父进程将通过wait()获知这一情况。
PTRACE_ATTACH: attach到一个指定的进程,使其成为当前进程跟踪的子进程,而子进程的行为等同于它进行了一次PTRACE_TRACEME操作。但是,需要注意的是,虽然当前进程成为被跟踪进程的父进程,但是子进程使用getppid()的到的仍将是其原始父进程的pid。
这下子gdb的attach功能也就明朗了。当你在gdb中使用attach命令来跟踪一个指定进程/线程的时候,gdb就自动成为改进程的父进程,而被跟踪的进程则使用了一次PTRACE_TRACEME,gdb也就顺理成章的接管了这个进程。
gdb调试的实现都是建立在信号的基础上的,在使用参数为PTRACE_TRACEME或PTRACE_ATTACH的ptrace系统调用建立调试关系后,交付给目标程序的任何信号首先都会被gdb截获。
gdb可以先行对信号进行相应处理,并根据信号的属性决定是否要将信号交付给目标程序。
gdb就是调用这个系统调用,然后通过一些参数来控制其他进程的执行的。
ptrace函数中request参数的一些主要选项:PTRACE_TRACEME: 表示本进程将被其父进程跟踪,交付给这个进程的所有信号,即使信号是忽略处理的(除SIGKILL之外),都将使其停止,父进程将通过wait()获知这一情况。
这是什么意思呢?我们可以结合到gdb上来看。如果在gdb中run一个程序,首先gdb会fork一个子进程,然后该子进程调用ptrace系统调用,参数就是PTRACE_TRACEME,然后调用一个exec执行程序。
基本过程是这样,细节上可能会有出入。需要注意的是,这个选项PTRACE_TRACEME是由子进程调用的而不是父进程!
以下选项都是由父进程调用:PTRACE_ATTACH:attach到一个指定的进程,使其成为当前进程跟踪的子进程,而子进程的行为等同于它进行了一次PTRACE_TRACEME操作。但是,需要注意的是,虽然当前进程成为被跟踪进程的父进程,但是子进程使用getppid()的到的仍将是其原始父进程的pid。这下子gdb的attach功能也就明朗了。
当你在gdb中使用attach命令来跟踪一个指定进程/线程的时候,gdb就自动成为改进程的父进程,而被跟踪的进程则使用了一次PTRACE_TRACEME,gdb也就顺理成章的接管了这个进程。 PTRACE_CONT:继续运行之前停止的子进程。可同时向子进程交付指定的信号。这个选项呢,其实就相当于gdb中的continue命令。当你使用continue命令之后,一个被gdb停止的进程就能继续执行下去,如果有信号,信号也会被交付给子进程。
除了以上这几个选项,ptrace还有很多其他选项,可以在linux下阅读man手册:man ptrace
需要注意的另一点是,使用gdb调试过多线程/进程的人应该都知道,当子进程遇到一个信号的时候,gdb就会截获这个信号,并将子进程暂停下来。这是为什么呢?
实际上,在使用参数为PTRACE_TRACEME或PTRACE_ATTACH的ptrace系统调用建立调试关系之后,交付给目标程序的任何信号(除SIGKILL之外)都将被gdb先行截获,或在远程调试中被gdbserver截获并通知gdb。gdb因此有机会对信号进行相应处理,并根据信号的属性决定在继续目标程序运行时是否将之前截获的信号实际交付给目标程序。
vim的使用,快捷键啥的
正则表达式
除了二分还有哪些查找方法?
一亿个url重复的问题【常规题】,说用hash分成小文件,被问到怎么分,具体怎么hash
手写算法:
1. strcpy
2. 最长公共子串
3. 不用>、<、if找出最大值的宏
#define MAX(A,B) (((A)-(B))>>31 ? (B) : (A))
4. 迪杰斯特拉算法
5. 求链表的中和最大的子串
6. 写一个字典树,数据结构自己定义,实现插入功能
7. N个有序的链表,将这些链表合并成一个有序的链表
8. 实现字符串分割,分割后每个word都在一个字典中,返回true,否则返回false
9. unix路径化简
//实际上就是截取所有的不含有特殊标志的字符串,然后对这个字符串进行比对。如果是..;如果是.;如果是简单的字符串,那么就放到向量vector里面。
int main()
{
string test;
getline(cin,test);
string path = test + "/";
vector<string>temp_result;
string result = "/";
int j = 0;
string temp;
for (int i = 0; i<path.size(); ++i)
{
if (path[i] == '/')
{
temp = path.substr(j, i - j);
j = i + 1;
if (temp.size()>0)
{
if (temp == "..")
{
if(!temp_result.empty())
temp_result.pop_back();
}
else if (temp == ".") {}
else { temp_result.push_back(temp); }
}
}
}
for (int i = 0; i < temp_result.size(); ++i)
result +=(i==0)? temp_result[i]:("/"+ temp_result[i]);
cout<<result<<endl;
}
10. 求2个集合的并集交集差集,我写出来,他问能不能在存储方面进行优化,我说只保留交集和差集
11. 一个数组,每个数字可以乘2任意次,最后能否让整个数组的数相等——【这题是用位移做吗??】
12. 将二叉树写成链表,再算时间复杂度。
13. 给定字符串以及关键词数组,返回高亮的字符串,注意关键词有公共部分的情况
14. 不用递归,深度遍历一个对象,对象有name以及children数组两个属性
15. 一个先升再降的数组,找最大值
16. 手写代码:输入一个字符串和一个整数k,将这个字符串每隔k字符,进行翻转
17. 字符串解码:4[c2[abd]]→字符串解码:4[c2[abd]]->cabdabdcabdabdcabdabdcabdabd
string translation(string& str, int ind){
if(ind == str.size()||str[ind] == ']'){
return string();
}
int num = 0;
while(str[ind]!='['){
num = num*10+str[ind]-'0';
ind++;
}
ind++;
string tmpres;
while(str[ind]>='a'&&str[ind]<='z'){
tmpres+=str[ind];
ind++;
}
cout<<tmpres<<endl;
tmpres+=translation(str,ind);
string res;
for(int i = 0; i<num; i++){
res+=tmpres;
}
return res;
}
18. 输入一个数字组成的字符串,要求出所有可能的ip地址组合
【依然是深度遍历】
void partitionIP(const string& str, int ind, string& tmpres, vector<string>& res, int partnum) {
//几个条件需要先满足一下
if (str.size() - ind>(4 - partnum) * 3 || str.size() - ind<(4 - partnum)) {
return;
}
if (ind == str.size() && partnum == 4) {
string tt = tmpres.substr(0, tmpres.size() - 1);
res.push_back(tt);
return;
}
int num = 0;
for (int i = ind; i<ind + 3&& i<str.size(); i++) {
num = num * 10 + str[i] - '0';
if (num <= 255) {
tmpres += str.substr(ind, i - ind + 1);
tmpres += '.';
partitionIP(str, i + 1, tmpres, res, partnum + 1);
tmpres = tmpres.substr(0, tmpres.size() - i + ind - 2);
}
if (num == 0) {
break;
}
}
}
19. 整型数组的最大字串
20. 写一个代码判断元素出栈的顺序是否合法
智力题:
烧绳子
25匹马五条赛道选出前三甲,需要跑几次——7次
<step1>把25匹马分为五组进行比赛,每一组都按成绩编号,1>2>3>4>5。可淘汰每一组的4,5,故现在还有15匹马待选。 这样已经比赛5次。
<step2>把每一组的第一名挑选出来比赛,a1>b1>c1>d1>e1,则d,e组都可以淘汰。现在还有九匹马待选。这样已经比赛6次。
<step3>
a123
b123
c123
由1和2中步骤知上表中a1一定最快,a2,b1可能可以竞争第二名的位置,a3,b2,c1可以竞争第三名,如此,其余的马匹被淘汰。让a2,b1,a3,b2,c1这5匹马比赛即可确定第二名,第三名。 这样已经比赛7次。
开发一面
面试官小哥很年轻,很热情,整场面试就像在探讨问题一样,涉及的知识点比较多。
1. 如何实现一个优先级队列
2. 说说常用的排序算法
3. 锁有哪些,作用是什么
4. Linux进程与线程通信机制
5. Linux下缓存机制
1)缓存机制介绍
在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件。当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果没有则通过驱动程序直接操作磁盘。
缓存机制优点:减少系统调用次数,降低CPU上下文切换和磁盘访问频率。
CPU上下文切换:CPU给每个进程一定的服务时间,当时间片用完后,内核从正在运行的进程中收回处理器,同时把进程当前运行状态保存下来,然后加载下一个任务,这个过程叫做上下文切换。实质上就是被终止运行进程与待运行进程的进程切换。
3)缓存区分buffers和cached区别
可用的memory=free memory+buffers+cached
buffers Buffer Cache和cached Page Cache 磁盘缓存的大小
-buffers/cache 的内存数:used - buffers - cached
+buffers/cache 的内存数:free + buffers + cached
A buffer is something that has yet to be "written" to disk. A cache is something that has been "read" from the disk and stored for later use.
缓存(cache)是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除。
缓冲(buffers)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。linux有一个守护进程定期清空缓冲内容(即写如磁盘),也可以通过sync命令手动清空缓冲。
6. Linux的I/O模型
7. Linux内存模型
8. Linux内核态、用户态、零拷贝
9. Socket连接过程
10. 你所知道的数据结构有哪些
11. STL容器内部数据结构
12. 红黑树的五种特性
13. 讲解MapReduce模型
14. Redis中的ReHash方法
15. 大数据问题BitMap和Bloom filter
16. 关于C++,平时读哪些书籍
17. 编程题:已知一个二叉树,每个节点有一个数值,用路径值表示该路径上所有节点值的和,求全局最大路径值
开发二面
这一面是最难受的一面,上来就是三道算法题,别的什么都没问。
1. 已知一随机发生器,产生0的概率是p,产生1的概率是1-p,现在要你构造一个发生器, 使得它构造0和1的概率均为1/2
2. 有两个排序数组,数组长度都为n,二分法求第n、n+1大的数
3. 判断链表是否有环,求入口位置,写出最优解以及数学推导
第一题就不会,心态炸了。当时的想法是设置一个全局计数器,第奇数次调用函数返回p,偶数次调用函数返回1-p,这样在宏观上看就是1/2。不过被说不符合题意。后面两道题虽然会做,但是紧张的写错了很多地方,没有达到二面要求。
最后面试官说:从这两道题看出你的过程化思维很严重,没有面向对象的编程思想,建议转岗测试。比如第二题要处理两个数组,可以把二分查找部分封装到一个函数里,第三题虽然简单,但要把原理完整推导出来。希望大家练习算法时不单单要会做,还要多手写,把函数命名、封装,算法的细节,数学推导都弄熟,不要输在细节上。
【第二题的思路——查找两个排序数组第n个数字】
取A数组的中间元素mid1,取B数组的中间元素mid2,先比较这两个元素的大小,如果这两个元素相等,则直接返回A[mid1],如果A[mid1]<B[mid2],则mid1左侧的元素可以去掉,B数组右侧的元素可以去掉,这里还要区分数组元素个数为偶数奇数的情况,如果元素个数为偶数,则mid1元素也要去掉。如果A[mid1]<B[mid2]的情况与此类似。时间复杂度为O(logn)
int mid(int a[],int b[],int n) {
int s1=0,e1=n-1;
int s2=0,e2=n-1;
int mid1=(s1+e1)/2;
int mid2=(s2+e2)/2;
while(s1!=e1||s2!=e2) {
mid1=(s1+e1)/2;
mid2=(s2+e2)/2;
if(a[mid1]==b[mid2]) {
return a[mid1];
}
if(a[mid1]<b[mid2]) {
if((s1+e1)%2==0) {
s1=mid1;
e2=mid2;
}
else {
s1=mid1+1;
e2=mid2;
}
}
else {
if((s1+e1)%2==0) {
e1=mid1;
s2=mid2;
}
else {
e1=mid1;
s2=mid2+1;
}
}
}
return a[s1]<b[s2]?a[s1]:b[s2];
}
测试一面
本来心情极度郁闷,但是跟面试官聊了一会儿渐渐调整过来了,问了我对测试开发岗位的看法,给我介绍了职业前景等等。之后聊项目,把项目中遇到的两个难点清晰的讲解一下。
1. 写一个字符串比较函数
2. 数组中乱序+、-两种字符,把+置左,-置右
3. 若数组中还存在0,说说思路
4. C++内存模型、什么是内存泄露
1. 概念:指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。
2. 对于C和C++这种没有Garbage Collection 的语言来讲,我们主要关注两种类型的内存泄漏:
(1)堆内存泄漏(Heap leak)。堆内存指的是程序运行中根据需要分配通过malloc,realloc new等从堆中分配的一块内存,再是完成后必须通过调用对应的 free或者delete 删掉。如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,就会产生Heap Leak.
(2)系统资源泄露(Resource Leak).主要指程序使用系统分配的资源比如 Bitmap, handle, SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。
3. 如何解决内存泄露?
内存泄露的问题其困难在于1.编译器不能发现这些问题。2.运行时才能捕获到这些错误,这些错误没有明显的症状,时隐时现。3.对于手机等终端开发用户来说,尤为困难。下面从三个方面来解决内存泄露:
第一,良好的编码习惯,尽量在涉及内存的程序段,检测出内存泄露。当程式稳定之后,在来检测内存泄露时,无疑增加了排除的困难和复杂度。
使用了内存分配的函数,要记得要使用其想用的函数释放掉,一旦使用完毕。
5. new、delete和malloc、free区别
6. STL线程安全与不安全
7. HashMap和HashTable区别
8. Python缩进、代码块如何定义
9. 黑盒测试和白盒测试区别
10. 假设搜索引擎只有一个文本框和按钮,如何做测试
测试二面
二面是个大姐姐,这么多次技术面还是头一次遇到,很不容易。整场面试更多考察的是解决问题的思路、想法。
1. 什么是Hadoop和MapReduce模型
2. 介绍Redis和AOF持久化
3. MySQL的两种引擎区别
4. 有两个表分别是<KB,KB>、<TB,KB>、<TB,TB>级别数据表,设计三种数据库系统以完成Join操作
5. 已知两个日期,求这两个日期相隔多少天
6. 如何测试一个冰箱,想一分钟再说
7. 有100个球(50红50蓝)和两个袋子,把所有的球装进袋子中,如何分配使得拿一个球为红球的概率最大
百度提前批(offered )
一面(55+minutes):
1.Java的三个特性
2.Java的spring介绍一下
3.Aop怎么实现的,写一下源码,动态代理和cglib
4.Java线程池介绍一下,里面的重要参数
5.在58实习的项目说说
6.信息脱敏项目怎么做的(我在这里说了guava缓存技术)
7.介绍一下缓存guava的用法
8.说说用过的一些rpc框架
9.聊了聊虚拟化云平台(PS:只是聊了聊大概,我也只是看了看几篇博客而已。。)
10.然后和我介绍了一下他们部门的各种业务和工作
二面(45+minutes):
这是我认为最难受的面试
面试官基本没问Java
1.计算机网络和操作系统轮番轰炸
Tcp三次握手,为什么三次握手(这里每一次面试官都要求详细解释,下同)
Tcp四次挥手,为什么四次挥手
2.Osi七层模型,每一层的作用
3.Tcp和osi的区别,osi和tcp谁出现的早呢?(面试官开了个玩笑)
4.为什么Tcp比osi用的广泛
5.DNS域名解析全过程,并且做详细解释
6.页面调度算法
7.介绍一下LRU算法
先入先出,最佳置换算法,LRU,clock算法。
8.介绍一下内核态和用户态的区别
如上图所示,从宏观上来看,Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核)。内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境。用户态即上层应用程序的活动空间,应用程序的执行必须依托于内核提供的资源,包括CPU资源、存储资源、I/O资源等。为了使上层应用能够访问到这些资源,内核必须为上层应用提供访问的接口:即系统调用。
系统调用是操作系统的最小功能单位,这些系统调用根据不同的应用场景可以进行扩展和裁剪,现在各种版本的Unix实现都提供了不同数量的系统调用,如Linux的不同版本提供了240-260个系统调用,FreeBSD大约提供了320个(reference:UNIX环境高级编程)。良好的程序设计方法是:重视上层的业务逻辑操作,而尽可能避免底层复杂的实现细节。库函数正是为了将程序员从复杂的细节中解脱出来而提出的一种有效方法。它实现对系统调用的封装,将简单的业务逻辑接口呈现给用户,方便用户调用,从这个角度上看,库函数就像是组成汉字的“偏旁”。这样的一种组成方式极大增强了程序设计的灵活性,对于简单的操作,我们可以直接调用系统调用来访问资源,如“人”,对于复杂操作,我们借助于库函数来实现,如“仁”。显然,这样的库函数依据不同的标准也可以有不同的实现版本,如ISO C 标准库,POSIX标准库等。
Shell是一个特殊的应用程序,俗称命令行,本质上是一个命令解释器,它下通系统调用,上通各种应用,通常充当着一种“胶水”的角色,来连接各个小功能程序,让不同程序能够以一个清晰的接口协同工作,从而增强各个程序的功能。同时,Shell是可编程的,它可以执行符合Shell语法的文本,这样的文本称为Shell脚本,通常短短的几行Shell脚本就可以实现一个非常大的功能,原因就是这些Shell语句通常都对系统调用做了一层封装。为了方便用户和系统交互,一般,一个Shell对应一个终端,终端是一个硬件设备,呈现给用户的是一个图形化窗口。我们可以通过这个窗口输入或者输出文本。这个文本直接传递给shell进行分析解释,然后执行。
总结一下,用户态的应用程序可以通过三种方式来访问内核态的资源:
1)系统调用
2)库函数
3)Shell脚本
下图是对上图的一个细分结构,从这个图上可以更进一步对内核所做的事有一个“全景式”的印象。主要表现为:向下控制硬件资源,向内管理操作系统资源:包括进程的调度和管理、内存的管理、文件系统的管理、设备驱动程序的管理以及网络资源的管理,向上则向应用程序提供系统调用的接口。从整体上来看,整个操作系统分为两层:用户态和内核态,这种分层的架构极大地提高了资源管理的可扩展性和灵活性,而且方便用户对资源的调用和集中式的管理,带来一定的安全性。
9.说说docker,自动化构建平台jenkins
10.项目最难受的地方是什么(我挖了个坑,我说写单测的时候,特别着急上线。。。结果又聊了聊单测)
11.自己设计一个电梯调度算法
12.你为什么会来百度呢?不想留在58么?
13.你所了解的百度
14.提问环节(这是比较开放的环节,所以就不记录了)
简单的聊了聊天,然后告诉我如果通过了会有人两天之内联系我(我自认为答得并不好,所以也就没再多问问题)
三面经理面(70+minutes):(果然很准时,第二天就联系我了)
1.Java的三个特性
2.你为什么会学Java呢
3.gc算法(这地方只说了大概)
4.jvm的内存模型,哪些是线程共享的,哪些是私有的
5.Redis用过么,为什么要学redis啊,怎么做集群
6.Redis的几种数据类型,优先队列的底层数据结构
Redis集群采用了P2P的模式,完全去中心化。把所有的key分成了2^16个slot。每个redis实例只负责其中一部分slot。集群中的所有信息(节点,端口,slot等)都通过节点之间定期的数据交换而更新。
Redis客户端可以在任意一个实例上发出请求。如果所需要的数据不在该实例中,则通过重定向命令引导客户端访问所需实例。
【所谓的集群方案,是指发送客户端命令给哪个实例???】
集群方案一:(静态的分片方案)
把分片的逻辑放到Redis客户端来实现,通过Redis客户端预先定义好的路由规则,把对key的访问转发到不同Redis实例中。最后把返回结果汇集。
好处是所有的逻辑都是可控的,不依赖于第三方分布式中间件。缺点是,这是一种静态的分片方案,需要增加或者减少Redis实例时,需要手工调整分片程序。
方案二:使用Redis代理。
redis集群提供了以下两个好处
1、将数据自动切分(split)到多个节点
2、当集群中的某一个节点故障时,redis还可以继续处理客户端的请求。
一个 redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。
集群中的主从复制
集群中的每个节点都有1个至N个复制品,其中一个为主节点,其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点,继续工作。这样集群就不会因为一个主节点的下线而无法正常工作
7.大学学过哪些课,印象最深的课程(我最难受的是回答了数据结构)噢,其实我想听的是高数和线代(我一脸黑线。。)
8.那说说各种数据结构的特点。。
9.两个栈实现队列,说说思路
10.聊聊实习的项目
11.Guava缓存策略为什么要那么设置(具体的设置我忘记了,在公司写的,已经过去一个多月了)
聊聊人生
12.你从上学到现在最艰难的决定是什么
13.成绩排名多少?最好的时候考过多少名?为什么不考研呢
14.你的爱好是什么呢(打篮球,特别热爱打篮球)
15.职业规划
16.随后面试官详细解释了我的一些疑问和不足,本人也很感谢面试官,也确定了本人未来的发展方向
其余的主观问题忘记了。。能想起来的就这么多了
百度一面:
1. 问基础,C和c++的,比如char str1[]="abc",char str2[]="abc", str1和str2是否相等。
如果是char*呢?
2. 一个struct的大小,c++多态的实现,虚函数的实现原理等等,很简单,秒杀。
3. 然后根据简历,看你会啥。问得很细,楼主是tcpip一些最基础的东西和多线程的东西,很基础,秒杀。
4. 还问了linux的一些东西,楼主不是很熟,就随便问了几句
5. 面试官然后出了2个算法题
一个是判断一个int有多少个1
一个是复杂链表的深拷贝,也是秒杀,然后就过了。
百度二面:
非常难啊。。以为挂了,来了之后问
1. STL熟悉么,喜欢什么容器。
2. 说到map,问map怎么实现,红黑树,红黑树是啥,红黑树插入操作是怎么样的,当时就懵逼了。我说红黑树的插入太复杂了吧,我写个AVL树的插入吧,然后给我一个树,让我往里面插数,反正就是左旋右旋啥的,没问题。
3. 然后让我写个堆排序,没写出来,就写了个思路。
4. 然后问数据库和linux的shell编程,(学过,不熟,出个题,直接说不会。)
5. 面试官无语了,问我会啥,我说c++,数据结构,操作系统,网络编程都还可以吧。然后就问了
c++的基础东西,问了STL源码里面有啥设计模式
其他的设计模式有没有接触,这个答得七七八八。
6. 然后做题
(1)实现一个返回栈中最小数的函数,设计了一个 类,很简单。
(2)然后最后问了一个,大数据,几亿个数据排序
百度三面:
1. 百度三面瞎聊吧,聊了聊毕设
2. 聊了聊图像处理和图形学的东西
3. 聊了聊人生和理想
4. 问了问快排的基本思想
5. 问单链表能用快排么?我说不行,为啥不行,一直问,最后问到不会为止。
6. 最后问了一个蓄水池抽样的问题,没听说过,他说没听说过更好,就说了问题,让我自己想有啥思路,7. 然后他在旁边提醒,最后基本说出来了,面试官感觉一般,让我滚了,也不知道过没过,说流程走完了,后续看HR吧。。
一面:
1、写算法,二叉树按层遍历,用双向链表把节点连起来
2、一个无序自然数数列,给定一个数M,选取自然数数列中两个数,其中他们的和是M,打印所有这样的自然数对
3、TCP UDP的不同 TCP三次握手
4、设计一个汽车摇号系统,当一个人摇了6年后抽到的概率会翻倍,设计这样的系统
5、Linux命令 在一个文件中,倒序打印第二行前100个大写字母
二面:
1、static_cast reinterpret_cast区别
2、class A{int m;}
class B{int m;}
class C:A,B;
C c;
printf("%p %p %p\r\n", &c, reinterpret_cast<B*>(&c), static_cast<B*>(&c)),三个结果打印有啥不同。
3、char c = 255;
unsigned short b = c;
cout <<b << endl;输出结果
4、继承中析构函数最好为虚函数为什么?
5、构造函数为什么不建议调用虚函数?
6、TCP UDP端口扫描的实现方式
7、TCP close_wait状态
CLOSE_WAIT
CLOSE_WAIT是被动关闭连接是形成的。根据TCP状态机,服务器端收到客户端发送的FIN,则按照TCP实现发送ACK,因此进入CLOSE_WAIT状态。但如果服务器端不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多CLOSE_WAIT状态的连接。此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。此时,recv/read已收到FIN的连接socket,会返回0。
如果服务器出了异常,百分之八九十都是下面两种情况:
1.服务器保持了大量TIME_WAIT状态
2.服务器保持了大量CLOSE_WAIT状态,简单来说CLOSE_WAIT数目过大是由于被动关闭连接处理不当导致的。
8、守护进程的概念,怎么创建守护进程
1. 在后台运行。
为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。
if(pid=fork())
exit(0);//是父进程,结束父进程,子进程继续
2. 脱离控制终端,登录会话和进程组
有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。
控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长:
setsid();
说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。
3. 禁止进程重新打开控制终端
现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:
if(pid=fork())
exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长)
4. 关闭打开的文件描述符
进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们:
for(i=0;i 关闭打开的文件描述符close(i);>
5. 改变当前工作目录
进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir("/")
6. 重设文件创建掩模
进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:umask(0);
7. 处理SIGCHLD信号
处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。
signal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。
9、线程间同步方式,条件变量
10、性能优化思路
11、手写代码 将一个数M转换转换成N进制
12、STL 内存分配方式
13、迭代器++it,it++哪个好
++i是在i上直接加1,表达式的值是i本身;
i++也是在i上加1,表达式的值是加1前的副本;
因为要存副本,所以效率略低,但是实际上大部分编译器都会完成这部分优化工作,但是对于自定义的迭代器之类的,就未必有优化了;
14、二叉树排序树逆序打印
15、STL中仿函数有什么用,和函数指针有什么不同,哪个效率高
【仿函数的一点整理——为什么要用仿函数?】
STL的算法函数,可以接受一个自定义的仿函数,包括函数指针。它的原型是:
template
Function for_each(InputIterator first, InputIterator end, Functin f);其中,Function是类型参数,(泛型)f可以传函数或函数指针或仿函数给它。
f将作用于容器中的各个元素,故它必须有一个参数或多个参数,此外它还可以有返回值。C++中根据仿函数的参数个数将它们分为一元和二元两类,同时又根据返回值是void或bool再进行分类。
问题来了。仿函数可以有多种类别,而STL某个特定算法函数,能接收的函数参数只能是其中的一种仿函数类别。如for_each只接受一元返回值为void的仿函数,而sort要接受二元返回值为bool的反函数。
这样就需要一种能够进行函数类型转换的solution,它就是仿函数。例如:
bool tooBig(int n) { return n > 100; }
list scores;
...
scores.remove_if(tooBig);
以上代码能够删除list中大于100的数,门限是“100”。但如果用户要指定门限,怎么办?修改tooBig函数?但是remove_if只接收一元的仿函数。
Solution:设计一个类,用类的成员变量来传递“门限”这个额外的信息。
template
class TooBig
{
private:
T cutoff;
public:
TooBig(const T & t) : cutoff(t) {}
bool operator() (const T & v) { return v > cutoff; }
}
16、select和epoll区别,select为什么慢
17、fwrite write fread read fopen open 区别,可移植性哪个好
18、多线程一个线程往一个数据中输入一些数字,另一个线程取出最大的两个数,用什么算法。【生产者消费者???】
19、堆的创建过程,怎么将无序的数组转换成一个堆
20、动态规划的应用举例
21、iptables的实现原理
22、快排是稳定排序吗,举个例子说明
1、自我介绍
2、项目经验
3、class和struct的区别
4、inline函数的作用
5、虚函数和纯虚函数的作用
6、纯虚函数能否被实例化
7、类中哪些函数不能够被设置为虚函数
8、能否用memset实例化一个类?
9、struct能否被继承
10、口述已知前序遍历和中序遍历顺序,求后序遍历结果,并简述过程
11、TCP三次握手的具体过程,为啥不能是两次或者四次
12、topK问题,求无序数组第k大的数字,算法的时间复杂度
13、new和malloc的区别
14、链表和数组的区别
二面
1、实验室情况,导师是否放人,实习时间能否保证
2、项目的一些细节问题
3、构造函数和析构函数能否为虚函数,为什么?
4、对死锁是否了解
4、OSI七层模型
5、TCP建立连接的具体过程
6、两个链表可能有环,如何判断是否相交
7、一个严格递增的数组,判断某个数是否存在的时间复杂度
8、假如数组不严格递增呢
9、如何得到数组中最大的前100个数,时间复杂度?
10、1G数据,现只有1M内存,如何得到出现频次最大的前100个数
11、除了堆排序、哈希,还有什么别的方法
百度C++研发一面
1:指针(各种指针,指针数组,数组指针,函数指针,n级指针)
2:char *a=new
char a[]
sizeof(a)大小
3:静态动态数组区别
4:new delete new[] delete [] malloc free底层实现
5:192.168.100.1 怎么存储
6:overload override(重载和覆盖)
7:unsigned long* p1=(unsigned long* )0x810000(地址)
unsigned char* p2=(unsigned char* )0x810000(地址)
p1+5=? p2+5=?
8:实现atoi(带无效字符)
9:快排思想
10:1000万个数,取出top100
可以堆实现和二分
11:两个杯子+50个红球+50个黑球,将100个球放入两个杯子,保证取出红球概率大的方法
12:tcp四次挥手过程
13:linux select poll epoll
14:怎么查看进程(ps aux)
15:time命令
time命令 用于 打印出一条命令或一个程序的执行时间
time 命令以秒为单位将一条命令执行期间所用的时间、系统时间和 time 命令的执行时间打印在标准错误中。
16:vim一些操作
基本上vi可以分为三种状态,分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下:
1) 命令行模式command mode)
控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode。
2) 插入模式(Insert mode)
只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。
3) 底行模式(last line mode)
将文件保存或退出vi,也可以设置编辑环境,如寻找字符串、列出行号……等。
不过一般我们在使用时把vi简化成两个模式,就是将底行模式(last line mode)也算入命令行模式command mode)。
2、vi的基本操作
a) 进入vi
在系统提示符号输入vi及文件名称后,就进入vi全屏幕编辑画面:$ vi myfile。不过有一点要特别注意,就是您进入vi之后,是处于「命令行模式(command mode)」,您要切换到「插入模式(Insert mode)」才能够输入文字。初次使用vi的人都会想先用上下左右键移动光标,结果电脑一直哔哔叫,把自己气个半死,所以进入vi后,先不要乱动,转换到「插入模式(Insert mode)」再说吧!
b) 切换至插入模式(Insert mode)编辑文件
在「命令行模式(command mode)」下按一下字母「i」就可以进入「插入模式(Insert mode)」,这时候你就可以开始输入文字了。
c) Insert 的切换
您目前处于「插入模式(Insert mode)」,您就只能一直输入文字,如果您发现输错了字!想用光标键往回移动,将该字删除,就要先按一下「ESC」键转到「命令行模式(command mode)」再删除文字。
d) 退出vi及保存文件
在「命令行模式(command mode)」下,按一下「:」冒号键进入「Last line mode」,例如:
: w filename (输入 「w filename」将文章以指定的文件名filename保存)
: wq (输入「wq」,存盘并退出vi)
: q! (输入q!, 不存盘强制退出vi)
3、命令行模式(command mode)功能键
1). 插入模式
按「i」切换进入插入模式「insert mode」,按“i”进入插入模式后是从光标当前位置开始输入文件;
按「a」进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字;
按「o」进入插入模式后,是插入新的一行,从行首开始输入文字。
2). 从插入模式切换为命令行模式
按「ESC」键。
3). 移动光标
vi可以直接用键盘上的光标来上下左右移动,但正规的vi是用小写英文字母「h」、「j」、「k」、「l」,分别控制光标左、下、上、右移一格。
按「ctrl」+「b」:屏幕往“后”移动一页。
按「ctrl」+「f」:屏幕往“前”移动一页。
按「ctrl」+「u」:屏幕往“后”移动半页。
按「ctrl」+「d」:屏幕往“前”移动半页。
按数字「0」:移到文章的开头。
按「G」:移动到文章的最后。
按「$」:移动到光标所在行的“行尾”。
按「^」:移动到光标所在行的“行首”
按「w」:光标跳到下个字的开头
按「e」:光标跳到下个字的字尾
按「b」:光标回到上个字的开头
按「#l」:光标移到该行的第#个位置,如:5l,56l。
4). 删除文字
「x」:每按一次,删除光标所在位置的“后面”一个字符。
「#x」:例如,「6x」表示删除光标所在位置的“后面”6个字符。
「X」:大写的X,每按一次,删除光标所在位置的“前面”一个字符。
「#X」:例如,「20X」表示删除光标所在位置的“前面”20个字符。
「dd」:删除光标所在行。
「#dd」:从光标所在行开始删除#行
5). 复制
「yw」:将光标所在之处到字尾的字符复制到缓冲区中。
「#yw」:复制#个字到缓冲区
「yy」:复制光标所在行到缓冲区。
「#yy」:例如,「6yy」表示拷贝从光标所在的该行“往下数”6行文字。
「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能。
6). 替换
「r」:替换光标所在处的字符。
「R」:替换光标所到之处的字符,直到按下「ESC」键为止。
7). 回复上一次操作
「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次“u”可以执行多次回复。
8). 更改
「cw」:更改光标所在处的字到字尾处
「c#w」:例如,「c3w」表示更改3个字
9). 跳至指定的行
「ctrl」+「g」列出光标所在行的行号。
「#G」:例如,「15G」,表示移动光标至文章的第15行行首。
4、Last line mode下命令简介
在使用「last line mode」之前,请记住先按「ESC」键确定您已经处于「command mode」下后,再按「:」冒号即可进入「last line mode」。
A) 列出行号
「set nu」:输入「set nu」后,会在文件中的每一行前面列出行号。
B) 跳到文件中的某一行
「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行。
C) 查找字符
「/关键字」:先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止。
「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往前寻找到您要的关键字为止。
D) 保存文件
「w」:在冒号输入字母「w」就可以将文件保存起来。
E) 离开vi
「q」:按「q」就是退出,如果无法离开vi,可以在「q」后跟一个「!」强制离开vi。
「qw」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。
17:gdb操作
18:大端小端问题,intel主机是什么模式
19:32位平台上内存对齐的问题
C++研发二面
1:爬虫项目
2:守护进程,libevent
3:poll epoll select
4:为什么select有文件句柄限制,poll epoll没有
5:网络聊天项目
聊天用什么协议(UDP),问什么使用UDP
微信qq用什么协议
6:跟多个人聊天怎么实现的(多线程),多线程怎么判断和哪个人聊天,需要设置什么全局变量
7:这里用到什么IPC(文件映射)
8:进程线程区别联系,多线程多进程
9:多线程有什么危险(加锁)
多线程中如果一个线程崩掉会不会造成整个进程的死亡
10:如果多线程一个线程没有释放锁,会造成什么情况,
11:如果多线程一个线程没有释放锁,那么他和单线程相比是否就没有优势了
12:TIME_WAIT状态
13:长连接短连接
14:如果利用短连接,大量线程同事访问服务器会产生什么后果,如果短连接,一次发送了大量的数据会产生什么后果
15:Hadoop,redis,大数据,云计算了解不?(不了解)
16:线程里面有什么资源,都有什么用处
(1)线程id(进程用这个来标记线程);(2)栈区域;(3)寄存器(PC寄存器,线程并行,调度切换);(4)信号屏蔽字;(5)errno;(6)优先级
17:如果一个人在公路上半小时遇到车的概率是0.9,那么10分钟之内遇到汽车的概率的是多少
18:二分图问题,一个导游安排一堆旅客住宿,每一个旅客对每一个房间有自己的满意度,问怎么安排房间保证所有游客对导游的满意度最大(根据满意度建边,跑一边二分图匹配)
19:你有什么问题
c++研发三面
聊理想,谈感情,说故事
问我的博客记录些什么
最后问了点linux (进程线程,僵尸,守护,孤儿) ,设计模式(单例模式懒汉饿汉,中介者模式) ,谈ACM经历
阿里巴巴 从3月底的一面断断续续到今天27号晚上已经进行了四面(我不知道为什么现在还在面试,正常应该结束了),不知道四面是否通过,
岗位也是c++研发
一面:
1:ACM经历,你刷过多少题?你们团队分工都是怎么样的?你最擅长哪些类算法?
2:topcoder,codeforge打了多少场,感觉怎么样
3:单源最短路你会哪些。说一下,时间复杂度都是多少?
dijska,spfa
4:dij能优化不?(堆优化和优先队列优化两种)
5:给你个图,已经源点和终点,问先从源点到终点,在从源点回到终点,最短路径怎么求?时间复杂度怎么样?
建立两个对称图搜索+标记+剪枝
还有什么方法?
跑一点最短路。另一遍进行搜索判断
6:vector内部元素内存不够了,内部怎么进行分配
7:mapset底层怎么实现的?插入删除复杂度怎么样
8:哈希表时间复杂度如何?冲突了如何解?
9:LRU模仿一下内部实现,实现insert函数(插入),get(获得头部元素,但是也相当于对头部进行查询)?
最开始用O(N)静态数组复杂度模拟两个函数.
能优化不?用堆+map标记时间复杂度降低到log(n)
还能优化不?
get函数使用双向循环链表,只是更改指针,时间复杂度降为O<1>,insert没想法优化到1了。最低logn
阿里二面:
找不到了记录了,半个月前的了,但是我记得最后一个问题就是从一个栈中获得最大的元素(在线coding)借助辅助栈
阿里三面:105分钟
1:谈一下信号量吧?
ans:linux和windows的信号量都说了一下.
说一下具体怎么实现的?
说了一下怎么具体实现的,我把函数都说出来了
设计一个生产者消费者模型,通过queue,且有上限。
通过信号量设计了一下,顺便把条件变量也可以实现类似的功能说了一下
2:你对c++内存这里有什么见解,或者有什么好的设计理念
自己总结了几点,new,detele,new[],delete[],构造析购里面通常怎么设计,虚析购的概念
3:后来他又给我讲解了一下c++喜欢用namespace这种机制,类似于析购构造的原理,一段结束后自动释放的原理。
我接着也说了一下自己对namespace经常用到的地方(1)自动锁的原理经常用到namespace,起到自动调用析购的函数(2)还有喜欢把一个class也封装在一个namespace里面,
4:设计的类似TCP的协议
(1)让你设计一种协议,A,B两个机器,A从硬盘不断的读数据流,并不断的像B机器发送,并且是有序到达的,你怎么保证B机器可以有序的收到,并且可以按顺序的读取?
我模仿TCP的滑动窗口+重传机制设计了一下
(2)如果不是有序到达的,多个消息并发到达,乱序的,你怎么处理?
在B机器对于收到的部分,我们设定head和tail指针,并且放在确认报文里面的首部选项里,以便A端可以重传.
(3)如果假设,我们每一次发送的数据,没有序号的概念,也可以理解为序号不是连续的,可能1,3,5,12,111之类的,你怎么处理?
我回答,从硬盘读取的顺序一定是一定的,那么根据读取的时间,我们手动的设定一个序号。
(4)我不希望有类似于序号的这个概念,你又怎么处理?
我回答的指针,从硬盘读取的时候,我们保证构造一个双向链表的模型,我们每次固定连续发送n个数据,B端收到后,对着n个暴力进行排序,读取之后,在发送给A端一个确认的回复,之后在循环进行
(5)我忘了他又怎么问了,不知道自己回答的对不对,但是我都没太明白他具体要实现什么,他开始不让用序号,最后他说了一下他的思路,好像还是用到了序号的概念,跟我第三问好像差不多,总之比较乱
5:从n个数中取出k个怎么实现?
堆时间复杂度n*logp
(1)可不可以在优化?
我说如果数的大小上限的差如果小于p的话,可以通过二分去解决,每次二分,看有多少个比mid大的数,感觉这种想法肯定不是他想要的,但是还是说出来了
(2)如果说只去第k大的怎么解决?
开始没想到,他问了我一句,快排的原理你还懂不?我立刻知道他想怎么实现了,之后马上说出了思路,他说其实快排解决可以将时间复杂度降为0(n),其实我感觉不是O(n),不知道他为什么这么说
(3)在线coding你的代码
下面是我在线10分钟左右敲完给他看的代码,其实事后我发现有几个地方出错了,当时coding没注意到,没法调试。除了下面3个错误,应该没有了,如果又发现的纠正意见
问题(1)l<r 这里面应该是l<=r,具体的原理自己模拟一下就知道了,虽然快排这么写不影响,但是这里影响
问题(2),(3):尼玛,忘加上return,(ps:编码一定不忘着急,犯这类低级错误)
return getNum(arr,head+1,r,k); //(2)
return getNum(arr,l,head-1,k-(r-head+1));//(3)
//coding
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int getNum(int *arr,int l,int r,int k){
int ans;
if(l<r){ //(1)
int head=l,tail=r,tmp=arr[l];
while(head<tail){
while(head<tail&&arr[tail]>=tmp){
tail--;
}
if(head<tail){
arr[head++]=arr[tail];
}
while(head<tail && arr[head]<tmp){
head++;
}
if(head<tail){
arr[tail--]=arr[head];
}
}
arr[head]=tmp;
if((r-head+1)==k){
return arr[head];
}
else{
if((r-head)>=k){
getNum(arr,head+1,r,k); //(2)
}
else{
getNum(arr,l,head-1,k-(r-head+1));//(3)
}
}
}
return -1;
}
int main(){
int len;
int arr[10000];
int k;
cin>>len>>k;
for(int i=0;i<len;i++){
cin>>arr[i];
}
int ans=getNum(arr,0,len-1,k);
if(ans==-1){
cout<<"error"<<endl;
}
else{
cout<<ans<<endl;
}
return 0;
}
6:讨论了一下我的博客,告诉我一定要把这种习惯坚持下去。以后益处会很大。
7:你有什么问题?
8:最后说建议你在多看一些更加深层的书籍,对你提高更加有帮助(我不知道这句话是不是意味着我三面失败的意思,不懂),总之,很好
阿里云四面
1 :字典树的概念,插入和删除需要注意些什么
2:字典树你有什么优化的地方
3:同样很多的字符串,你怎么尽可能少的压缩空间去存储,设计一种数据结构实现,不能使用字典树
4:对于I/O你有什么积累的经验,对于read/write出错了你有哪些解决的办法?
5:异步+事务:对于一些异步事件,怎么保证当调用失败的时候保证整体的完整性?
6:你看过***源代码么(忘记了,自己没听过)
7:说一下你最近你感受最深的项目吧(由于正在***公司实习,参与了一个项目,,正好说了一下)
8:为什么想加入阿里?
9:你有什么问我的吗?
阿里巴巴,蚂蚁金服(二面跪)
阿里巴巴跪了首先确实是因为自己能力不足,其次是因为自己作死投了JAVA岗(本人主要会C++)。
一面:
1.实习经历
2.说一下迪克斯特拉算法
3.LinkedList和ArrayList区别
4.B树B+树
5.一致性哈希
6.图的的环检测(深搜)
7.对称加密与非对称加密
8.还有些东西时间有些久远不记得了
二面:
1.写堆排序
2.二叉树先序遍历(用递归和非递归)
3.TCP三次握手,四次挥手
4.说自己的项目,怎么优化
结果GG
百度运维部(三面跪)
一面
1.TCP三次握手,以及为什么不是两次或四次
2.TCP四次挥手状态,为什么要有time_wait,以及如何避免
3.文件系统实现
5.proc文件系统(meminfo,cpuinfo)
6.Linux命令查看文件大小
7.布隆过滤算法
8.项目,如何改进
二面
1.全程谈实习
2.问了一个堆排序,然后堆得作用
3.Topk
4.将一个只含有1~n的乱序数组(不重复)的第一个数变成-1,求哪个数被变成了-1
问面试官我进去做的是运维还是开发,被他教育了一番,但他说还是给我过了
三面
1.输入baidu.com是怎么通信的
2.能不能来实习
3.。。。剩下的不记得了,被虐了
结果GG,被自己菜醒。。。
好未来(拒offer)
一面
1.二叉树高度(递归,非递归)
2.一个数组只有一个数不重复,找出这个数。
3.一个数组有两个不重复,找出这两个数
4.写一下堆排序
5.虚函数实现机制
6.一个硬币,有A,和B两人投币,A先投,正面A赢,反面B继续投,B投到正面算B赢否则A继续投,这个规则持续下去求A赢得概率(等比数列公式忘了*_*)
7.Java与C++区别
8.怎么学习的
二面
1.快排如何优化,快排与堆排优缺点
2.设计一个类,...忘记了
3.static作用
4.讲项目
5.愿不愿意转算法方向
结果offer
美团 餐饮(offer)
一面
1.meituan.com通信过程
2.TCP三次握手,四次挥手,状态
3.虚拟内存机制
4.缺页操作系统如何处理
5.什么是elf头文件
6.写快排,二分,单例
7.volatile作用,内存屏障
8.Java与C++区别(从模板,编译,链接,内存,库几个方向解释)
二面
1.给一个字符串数组和一个字符串S,找出字符串数组中所有的字符串s符合规则:s通过删除,增加,替换一个字符可以变为S。
2.简单讲讲操作系统内存管理机制,段式与页式内存管理的优缺点(顺道讲了下段页式)
3.知道sendfile吗(表示不知道),啥是NIO(小白表示没听过。。。)
4.RPC实现(答得很烂)
5.讲一下一个C文件的编译链接过程
6.B树B+树
7.讲实习,讲自己的项目
上来这个面试官就说前面的算法太简单,来个稍微难点的第一题,(也不算难吧*_*。。。
三面
1.45度斜线打印二维数组
2.讲一下网络通信协议栈
3.TCP和UDP区别,TCP如何保证可靠性,time_wait,TCP有哪些缺点
4.HTTPS如何实现
5.什么是缓存,为什么需要缓存,有哪些缓存使用场景
6.最近看了什么讲一下,讲了一下GFS的核心和mapreduc
4个瓶盖换1瓶酒,要喝150瓶酒,他自己最少买多少瓶?
8.聊了下人生
结果 offer
腾讯 SNG QQ音乐(拒offer)
一面
1.vector与list区别
2.什么是traits,作用
3.迭代器失效
4.unorderd_map如何实现
5.模板两种特化,作用(要求根据STL讲,再配合traits说了下)
6.说一下yacc和lex,递归下降
7.tcp/ip...(这个答得都快吐了,参考前面
8.深拷贝浅拷贝,右值引用,智能指针,引用计数,循环引用如何解决
二面
1.两个排序数组合并成一个排序数组
2.游戏(农药)用的TCP还是UDP为什么
3.Epoll与Select区别以及epoll优点,为什么一般情况下epoll性能比select好,ET模式与LT模式
4.Epoll ET下非阻塞读,为什么不能是阻塞
5.发送3个80字节包,TCP与UDP下对端分别接受几次(其实就是TCP与UDP区别之一,TCP基于流)
6.实习,项目
三面
1.如何判断一个数是2的次幂
2.快排
3.还有些不记得了,回答的不是很好
4.谈谈理想啥的
百度云计算事业部(offer)
一面
1.给一个先序序列,重构完全二叉树,如果是一般二叉树能不能重构,为什么(QQ写代码_)
2.有三个消息队列,随机的向三个队列插入元素(概率可能不同),如何保证插入和查找的高效(有两种思路,一种是加一个控制器,队列通知占用率,由控制器控制插入和查找,另一种是计算阻塞次数,再根据阻塞次数按比例控制该队列的插入频率和查找频率)
3.最长公共子序列
4.vector的拷贝,swap函数交换指针
5.线程与进程区别,优缺点,进程内存模型
6.IPC有哪些,共享内存原理
7.说一下LRU cache思路
8.赛马问题,36匹马,6个赛道,找出最快6匹马的最小赛马次数,如果是n匹马,m个赛道呢
二面
1.虚函数实现机制
2.内存模型影响因素(内存对齐,多重继承下的内存模型,菱形问题,虚拟继承内存模型,虚拟继承是如何处理的)
3.NRVO优化,右值引用
4.extern C作用,为什么需要
5.C++重载,name manging机制
6.Epoll与Select区别以及epoll优点,为什么一般情况下epoll性能比select好,ET模式与LT模式
7..如何用epoll实现高并发,多线程,线程池,线程惊群问题
8.二叉树先序遍历,递归,非递归,如何用O(1)空间实现(morris 遍历)
9.互斥锁的实现原理(屏蔽中断,CAS),读写锁实现
三面
1.实习,项目
2.TCP拥塞控制,滑动窗口协议,糊涂窗口
3.虚拟内存机制,二级页表,TLB快表,缺页,swap
4.操作系统调度算法
5.TCP如何保证可靠性,四种定时器,time_wait如何解决,Nagle算法
6.一致性算法(raft),一致性哈希
7.优点缺点,是否愿意来实习
15分钟写一个判断字符串是否为合法字符串的方法
n个无符号整数找第k大,要求最坏O(n)时间复杂度,O(1)空间复杂度
static的特性
对于char,int这些怎么实现sizeof
c 怎么分配内存,如果分配不成功会发生什么?怎么处理?不捕获异常能不能直接处理,提示强制转换
c 内存分为哪些区
大端小端
进程通信方式
信号安全
io写操作之后会立刻发出去吗
画三次握手四次挥手
Server端有两个队列,哪两个
MTU,MSS是什么
客户端发送fin在c里是哪个函数
客户端发送fin后如果还有消息未处理会发生什么
客户端什么情况会出现很多time_wait
2017微软转正实习生
第一面没问算法,直接问项目,首先我解释了几个课程设计,后来按着机器学习一直问。。没怎么回答好。。后来讲了一下简历写的个小游戏。
二面开始问我迷宫查找怎么实现的,就是深度优先和广度优先的搜索。问了俩算法,比较简单:一个是树的层序遍历,另一个求经过root的两个树节点之间的路径长度。手写代码,讲思路和测试用例。另外引申了一下求两个节点的不经过root的最短路径长度。我说要求最近公共祖先,但是代码还没想出来咋写呢,时间也差不多,就结束了二面。
三面竟然问一些语言特性。。java hashmap 和 hashtable的区别(线程安全)。。c++ virtual, 析构函数,重载重写。按着线程安全的问题问啊问。。我就知道互斥锁。。最后给看了一个c语言strtoken函数的定义,然后白板实现。自我感觉这个函数写的差不多,就是前面一些语言特性没回答好。。 对了,因为strtoken 不是线程安全的,面试官又问我该咋办。。我又只能回答说加锁。。。。。。
微软的消息等了太久了!!备胎一个月了,苏州那边打电话问我能不能去苏州实习。。然后说不太可以。。毕竟学校在北京。。然后GG了。。现在后悔,不该为了怕导师而拒绝微软啊,校招的时候还是看实习的。 啊心塞。。。如果给我一个机会。。我肯定会请一个月假加上暑假去的,没实习现在校招特别难受,而且感觉再也没机会去微软了。
小米实习面试
1 最近公共祖先。 如果有parent 指针, 相当于求两个链表的交点了。如果是普通二叉树就递归判断。 当初没好好刷题呀。https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/
2 旋转数组二分查找
最后小米实习去了一周。迫于导师淫威, 怕怕地辞职了。太怂了。。而且等我辞职后竟然放假了并且导师也对我们找工作放水了!! 又心塞!!!
头条实习面试
一面挂。 问求第k大个数字。用快排写的。 写的比较慢。 又问项目。感觉没亮点。 挂!
360中科院专场
面试真的靠缘分和运气吗,感觉水过的。
一面问,写个atoi吧,考虑好各种情况。 我就写。。刚写了两分钟,面试官忍不住了,你咋写这么多。。。我说我得考虑充分啊,他说别写了讲讲吧。。。就讲了下。然后又问,编辑距离知道吗?我说动态规划,刚要写,然后他说好,知道了不用写。然后问了下svm,gbdt 的东西, 就过了
二面说,山东人啊。。360好多山东人呢。。哎你这项目都是工程的呀,咋来找算法,我说因为热爱 = =(内心:我就是试试看啊)。 没写算法题,聊了聊项目,问svm 折页损失公式,并问L2正则作用。竟然过了(黑人问号??)
三面hr: 自我介绍,优点,对360的了解, 对人工智能研究院的了解。。。
百度本地凤巢
一面:由于我简历写的熟悉java, c++略懂,他就问了下简单的c++的语言特性, const 关键字。面试官很nice,告诉我别紧张。。就想了解一下我会的东西。然后问了排序,按某种分类把排序算法分类一下。我按时间复杂度分的。后来又问了下各个排序的原理讲了一下。 算法题:记不太清了,就是一个二叉树遍历的变形,输出二叉树中路径尾节点能被5整除的路径?写了个递归的,又问非递归的。。大致说了下。他问,是不是刷题挺多。。我说,大家都会刷一些吧。。。问用linux开发吗?我说写过c/c++ makefile。 面试官就噼里啪啦记录。
二面:shell 命令。。不熟, 问怎么用shell脚本写内存监控,直接说不会。 后来又让我用shell查找统计一个文件里的几行记录,我说我用sql吧。。。。面试官无奈地点头了。后来问 linux 读文件的时候内核发生了啥?然后问了selector, poll epoll... 当时都没看(现在也没来得及看~~(>_<)~~), 就记得selector 监控多个io通道啥的,大致说了下。 算法题: minstack. 参见剑指offer,但是第二个栈不用每次都push min
三面:开放题。 问了搜索相关的。 问好多url,里面可能有好多重读字段怎么存储。开始说前缀树,想了想,说先按照? / 分词, 存储倒排索引。面试官莫名觉得我不错,但我自己感觉二面三面答的都不好。
最后百度提前批只有这一个部门过了,刚刚笔试完,还没收到通知。又是无尽的等待。。
百度金融
一面 java 内存结构, 程序计数器存的啥?为啥建立连接三次握手,而释放连接要四次挥手?(把过程说了下,说四次挥手是因为服务器还要发数据给客户端,发送完毕后还要确定一次,不知道对不对)算法题:1)两个字符串中,一个字符串相比另一个字符串少了一个字符,找出来这个字符。 我说排序后用双指针或者hash表,写了代码。2)算 a + b, 不能用加号或减号。说了用位运算,但是进位那里卡壳了,正确答案见http://blog.csdn.net/unimen/article/details/6776138
int add(int num1, int num2)
{
if (0 == num2)
return num1;
int sum = num1 ^ num2;
int carry = (num1 & num2) << 1;
return add(sum, carry);
}
3) 二叉树中序遍历,递归 非递归都写了遍。。。
二面, 问项目,然后看到我有个模拟挖矿(比特币相关的东西)的小应用,和金融比较相关,就简单介绍了下。以为我懂区块链之类的,然而并没有。算法题!链表带random指针深拷贝的问题!! 我竟然忘记咋做了,一直在想不用hash表的那种算法,最后面试官提示可以用额外的数据结构,就说了用hash表存原节点和新节点的关系。完整答案:http://www.cnblogs.com/chrischennx/archive/2014/10/15/4026101.html
三面 人生理想,职业规划,性格优点。 然后说我不大自信。以后面试要自信
链家
5个笔试题,现场笔试后再面试。
笔试
1 数组中超过一半的数。 http://blog.csdn.net/lskyne/article/details/9360639
2 括号是不是合法匹配, 用了个栈
3 m个连续珠子有n个不同的颜色,求最小包含n个颜色的连续珠子长度 http://blog.csdn.net/zhccl/article/details/8044449
4 一堆ip访问记录(ip, 时间),如果10分钟内连续访问超过1024次就是非法的,找出这些非法ip
5 判断循环依赖。(图里是否有环,应该是用拓扑排序)
一面: 线程有没有自己的独立资源? 三次握手过程。 b+树 data存在哪?(叶子节点),叶子节点有联系吗?(有,链表相连的形式)为啥?(方便遍历,区间查找) 你觉得笔试题能答多少分?我说七八十吧,他说差不多。说他觉得没啥问题了, 问了解链家吗,我说。。租房卖房的吧。。。北京好多门头店啊。。。最后又说链家技术不错。。
二面: 鄙视我的项目,觉得太简单。。 哎, 我也知道啊。。我也很绝望啊。。。写了个sql,问职业规划,我说做搜索相关的吧。。他说链家没有。。我说比较偏算法的研发吧,他说这说法好虚啊。。。最后说 嗯你等一下我考虑一下吧。。。然后过几分钟给我挂了。 感觉职业规划真的挺重要的,虽然之后不一定按自己说的做,但还是要大致有个规划,让面试官觉得 你这个人是对自己负责的。 所以我职业规划是什么,我研究生上的这么杂我也很绝望啊。。。。
网易有道
算法岗, 不match. 记得一个题大约是:
http://www.cnblogs.com/huangwei1024/archive/2012/09/28/min-len-substring.html
百度运维
数据库索引 用了什么数据结构, 和红黑树区别
hashMap 初始化多大, 什么时候重新扩容
两个链表判断是否有交点
翻转字符串 in-place "how are you" 转成 “you are how”
三次握手; 四次挥手什么时候是在 time-wait 状态
http 协议组成部分
jvm 垃圾回收, cms 收集器
elatic search 索引合并?
线程 interrupted 是进入什么状态
读写锁 : 读写锁特点:
1)多个读者可以同时进行读
2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)
3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
jvm OM 异常 通常是怎么个情况, 如何调优。。。
华为优招
啥也没问基本。。聊项目也有没有引申出一些知识点
祖龙娱乐
1 给一个java 程序,说出执行期间,jvm各个内存存储数据的变化,包括各个变量存储在哪,对象构造的过程,程序计数器,栈的压栈返回过程。然后评价我答的不太具体,只是说了各个数据的存储区域。
2 申请了很多 对象, 会出现什么问题? 各个内存区域都有可能因为什么而出现问题?
3 垃圾回收算法
说了eden和 survivor 后, 让具体描述那个 8:1:1 怎么复制回收的
4 判断html 字符串是否合法, 给合法的标签列表, 要合法不能不同的标签相互交错。
5 account (aid, money)
设计 addMoney, subMoney transMoney(Account a, int money) 的线程安全的算法。
我写了之后,忘记考虑money的正负 是否溢出的情况,把我鄙视一番。 还有转账的方法, 两个对象都加锁,会造成死锁产生, 他问我咋办,我说一次都申请了,写的代码成了整个串行的了。 最后才想到 按顺序申请,可以每次先给id小的account对象加锁, 然而他已经对我彻底失望。其实感觉一开始就对我没抱希望的样子。
头条校招面试
一面:
(1)大文件100亿个数字,求前m大的数
(2)进程和线程区别,啥时候应该用多线程,啥时候用多进程。 线程的好处? 协程? <a href="http://www.cnblogs.com/lxmhhy/p/6041001.html" target="_blank">http://www.cnblogs.com/lxmhhy/p/6041001.html (3)索引为何用b树 不用二叉树 </a><a href="http://database.51cto.com/art/201504/473322_all.htm" target="_blank">http://database.51cto.com/art/201504/473322_all.htm 索引很大需要存到磁盘,高度小了,需要的io操作少
(4)两个有序数组,求第k个数, 说了双指针的做法,O(k), 面试官让想更优的, 没想出来。应该是用二分查找的方法。 </a><a href="http://bookshadow.com/weblog/2015/02/05/find-kth-smallest-element-in-the-union-of-two-sorted-arrays/" target="_blank">http://bookshadow.com/weblog/2015/02/05/find-kth-smallest-element-in-the-union-of-two-sorted-arrays/ (5) 看什么技术类的书籍,讲讲jvm里都讲了啥。</a>
二面:
1
2
3
面试官脾气很好。。问了下数据库事物隔离,一开始说不大了解,突然想到之前看了脏读,不可重复读,幻读。。说了之后面试官也没深入问。<a href="http://www.cnblogs.com/zhoujinyi/p/3437475.html" target="_blank">http://www.cnblogs.com/zhoujinyi/p/3437475.html 然后问mysql的一些问题,为何一般不用select *, 要用select 需要的字段呢?尝试回答了,不大对,面试官就解释了一遍。。我忘了他讲的啥了。。。好像之前还被问到 limit 分页的数字大为啥效率会变低。。数据库不太了解。
然后问一个shell, Ctrl+C 发生了啥。。我扯了一堆进程销毁的过程。。结果面试官是说和信号量有关。。尴尬。。
算法题。。面试官拿了俩题,让我选,我一看。。最大连续子数组和。。。然后写完了, 扯了一会,说。。你写个二分查找吧。。我就迅速写了个。。 他看了一眼。。然后结束了面试。。</a>
三面 :
问了jvm的, gc, 怎么判断对象存活。 volatile(两个特性) sychronized:
修饰一个类,其作用的范围是synchronized后面括号括起来的部分, 作用的对象是这个类的所有对象。
修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法, 作用的对象是调用这个方法的对象;
修改一个静态的方法,其作用的范围是整个静态方法, 作用的对象是这个类的所有对象;
修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码, 作用的对象是调用这个代码块的对象; <a href="http://wiki.jikexueyuan.com/project/java-concurrency/synchronized.html" target="_blank">http://wiki.jikexueyuan.com/project/java-concurrency/synchronized.html 实现LRU O(1) 但是面试官描述得有问题,说使最近用次数最少的blabla..,我说你说的是LFU啊,不是LRU. 他说差不多!!??说了LRU的数据结构,他又说加过期时间怎么整。。 我只能想到O(n)遍历删除的。
后来写了求树中两个子节点直接最长距离的。。差点没写上来。 一开始想对每个节点求左右高度,有重复计算,后来写代码时,就想到在递归中可以求一遍就好了。写好了面试官问了下边界情况,检查了下没问题。。然后说今天面试结束了,日常提问环节。。 瞎问了点问题。。</a>
最后面头条的感受:感觉面了假的头条。。 头条实习一面挂的阴影还在, 咋还能给我终面过了。。面试真是运气+眼缘啊。。忐忑。。 hr说九月中下旬给通知,不一定给offer
小米内推
一面: 瞎扯项目, 算法题: 二维数组中,每个元素有个数字,求某一个点到任意一点的sum和(只能向右或者向下) dp记录到每个点的sum。 第二个题, 求一个字符串,包含一个字符集的最短长度。网易有道一面题
二面: 项目,讲了java 内存。进程线程。 26进制转换。 一堆ip中,查找一个ip是否存在。
作者:狗头兽
链接:https://www.nowcoder.com/discuss/48182?type=0&order=0&pos=94&page=1
来源:牛客网
腾讯暑期实习电面:
1.对windows中消息机制的理解。
2.SendMessage与PostMessage区别
3.GetMessage与PeekMessage区别
4.对C++多态的理解。
5.函数重载如何实现。
6.动态多态如何实现——虚函数表指针。
7.虚函数表有多少张。
8.public继承与private继承。
9.STL中vector与list的区别。
10.如何实现线程同步。
11.死锁的条件。
12.如何安全结束一个线程。
腾讯电面:
1.实习中最大的收获,遇到的困难。
2.游戏中大量资源,如何提高文件的读写效率。
3.MMORPG游戏使用的是TCP还是UDP,如何解决UDP丢包问题,TCP的性能慢在哪。
4.项目中最有技术含量的点。
5.A*算法要点。
6.最近看什么书。
7.lua为什么不用编译就可以执行
网易实习一面:
1.extern‘C’的作用
2.函数重载的实现,与返回值、函数名、类型数量、类型有关?如果形参为const int与int能重载么。
3.成员函数末尾带const表示什么,如何在const成员函数中改变数据成员。
4.虚函数指针是否肯定占据对象前几个字节,在32,64位系统中多少字节?
5.虚函数表,如何访问到虚函数表中的函数地址。
6.vector、list、deque。
7.vector初始时容量。
8.vector迭代器失效什么时候发生?
9.unordered_map是由什么实现。
10.哈希表的冲突处理方法。
11.开链法的缺点。
12.红黑树为何优于平衡二叉树(AVL)?
13.C++四种转换,static_cast与dynamic_cast用来进行父类子类转换的区别。
14.多线程跟多进程的区别。
15.32位系统进程可占有多少内存(4GB),64位呢?
16.TCP连接的四次挥手。
17.发送一个数据包的时候,seq与ack与包大小的关系。
18.发送数据包后网络层发生了什么?
19.TCP的异步方式原理。
20.cocos2d的垃圾回收机制
网易一面:
1.代码测试:实现STL中的push_back
2.函数内static与函数外static
3.栈上对象与堆上对象比较
4.extern “c”作用
5.含虚函数的类size of
6.deque模型
7.PeekMessage与GetMessage
8.模板template
9.VC++的Runtime Library设置的作用,没用过,过
10.lua table如何计算数组与map长度
11.10万个数据如何求多少个组合使得两个数相加得12345
12.tcp、udp的步骤解析,bind,listen,accept各自的作用
13.tcp连续两次send,会receive几次
14.tcp发送消息,应用层如何确定接受已经完整了
15.是否用过非阻塞的模型,用的是MFC类库带的,没具体了解,过
16.如何为stack实现max()函数,记录stack最大值(《剑指offer》)
17.如何使cpu保持20%(《编程之美》)
网易二面:
1.自我介绍
2.讲下项目
3.vector容积从1开始,push_back N个元素的时间复杂度。
4.爬虫获取10亿个页面数据,用什么存储;如何匹配多个关键字,匹配后不同的页面数据有不同的相关值,用什么存储。
5.上亿个url,十万个服务器,如何存放,能迅速响应用户请求。
6.最大子串和,时间复杂度
7.最大子矩阵和,时间复杂度
8.有没考虑读研
9.未来发展规划
作者:会飞的鱼_fly
链接:https://www.nowcoder.com/discuss/48218
来源:牛客网
岗位:测试开发
我的秋招已经接近尾声了,目前拿到了滴滴,58,链家,电信it研发中心的offer,在等头条、腾讯和百度的结果。秋招面了的公司除了这7家还有搜狐和美团,搜狐面试体验不好,感觉二面面试官不尊重我(不是压力面,就是不尊重),所以我态度也不太好,面完hr说我那天的面试通过了,回去等通知,然后就没有然后了。美团是内推免笔试的,远程面了3轮技术面然后就没消息了,说实话我回想了一下三轮面试基本没什么问题,该答的该写的我都答的不错,就是想不通哪个环节出了问题。现在我就按我面试的顺序跟大家分享一些面经和感悟吧。大多数面试我面完回来没写面经,因为感觉太累了,所以只能大概的回忆一下。
一、链家(内推的,笔试完八月底去北京现场面,2轮技术+1轮hr)
链家是我秋招面试的第一家公司,专门跑了一趟北京现场面的,链家工作环境不错,hr姐姐也很nice,面试官整体也还不错,之前已经写了面经,传送门:https://www.nowcoder.com/discuss/35261。
二、58(内推笔试,2轮技术面+1轮hr面,视频)
一面:45min,
没有让自我介绍,直接上问题
1、挑一个印象深刻的项目,讲一下遇到了什么问题,如何解决的。
2、C++预编译是什么?做了哪些工作?
3、C++内存泄露
4、一个10G的文件,存放了用户的访问记录(每次记录占1行),如何找出访问频率最高的前10个?
5、25匹马,5个跑道,如何在最少的比赛次数内找出最快的三匹
6、Linux如何找出10天内修改过的文件
7、一个链表,如果找出最中间的结点(答了三种方法,最优的是用快慢指针)
8、数组和链表的区别
9、堆和栈的区别
10、数据库了解吗?平时用的什么数据库?(我说了解的不多,所以只问了一个问题)
11、数据库索引作用?有哪几种
12、SQL语句找出班级成绩排名50-100的同学姓名
13、URL解析的全过程
14、除了web服务器,还了解什么服务器?(答了负载均衡服务器,让我具体说了一下作用、负载均衡服务器用在刚才说的URL解析的哪个步骤、比较流行的负载均衡服务器有哪些)
15、200个数存在数组里,数字大小在1-100以内,如何找到出现频率最高的一个,不能用辅助内存
16、排序算法时间复杂度
17、多线程同步互斥机制
18、线程池作用
19、哪些应用用到TCP,哪些是UDP
20、进程间通信方式
面试难度还可以,都是比较基础日常的问题,没有问测试的东西。
二面:30min
1、自我介绍
2、介绍两个项目和论文,针对项目提了几个问题
3、C++内存泄露了解吗?如何避免?
4、测试的作用是什么?
5、C++常用的数据结构有哪些?具体的应用场景?
6、HTTP协议了解吗?HTTP报文格式?
7、Linux常用指令?ps命令的参数有哪些,含义
8、测试都要做哪些工作?回答的里面有接口测试,又问了我接口测试是什么?什么是接口?
9、性能测试做什么工作?
答了压力、负载等,又问了压力测试怎么做?我举例说比如模拟1000个用户并发登录;又问我如何用C++代码实现这
1000个用户的并发,我说用多线程编程,结合线程池;他说如果不用线程池呢,没想出来(后来问了他这个问题怎么搞,
他说试题答案不方便同步,巴拉巴拉的,我猜是他也不知道答案)
10、如何启动线程?
11、设计测试用例,如何测试优酷视频客户端
12、哈希冲突处理方式
13、有什么问题要问他
hr面:20min
hr面常问的一些套路问题。。。
三、美团(内推免笔试,3轮技术面,1面3面是电话面,2面牛客网视频面)
一面:1h10min
1、自我介绍
2、输入URL的具体响应过程
3、刚才讲述的URL过程涉及到哪些协议,具体讲一下相关的协议内容(DNS,TCP/IP,HTTP,ARP)
4、HTTP常用的方法有哪些?POST和GRT区别?
5、session和cookie的理解?
6、了解SYN包吗?讲一下具体应用(讲了TCP三次握手过程,主动讲了TCP超时计时器可以保证可靠传输,又问了 TCP还有什么保证可靠传输的机制,握手+拥塞控制)
7、SYN Flood了解吗?具体解释一下现象和原因,解决方法
8、socket编程过程(服务器+客户端,结合三次握手讲了一下)
9、智力题:一个圆桌,AB两个人放硬币,A先放,先放不下的人输,A如何放才能保证赢
10、智力题:8个球,1个球比其他7个重,如何用一个天平秤2次找出重的球
11、简历写了学习了JMeter,主要学习了什么,用它做了什么,如何用它做性能测试
12、C++编译链接的全过程(预处理+编译+汇编+链接)
13、静态链接和动态链接区别?
14、静态库和动态库后缀?(答了.lib和.dll,她说你说的是windows下面的吗,我说是的。不过我也不知道linux下的啊。。)
15、静态链接的时候显示undefined reference to的原因有哪些
16、C++虚继承的作用
17、C++智能指针
18、C++ define和const区别?
19、C++ static成员函数和成员变量是什么?什么时候需要用到静态成员变量?
20、C++ 深拷贝和浅拷贝
21、STL了解哪些?(讲了vector、list等,让我讲了区别,vector的底层实现机制)
22、写了两个数据库SQL查询语句,比较简单
23、Linux用过吗?查看当前目录指令?
24、查看进程指令?(答了ps,又让讲了ps的参数和作用)
25、查找某个文件后100行中子串word出现的行
26、功能测试包括哪些方面的测试?
27、功能测试有哪些方法(答了等价类,边界值,因果图,让解释了一下等价类)
28、测试电梯,设计测试用例
二面(40min)
1、自我介绍
然后直接写代码,比较简单,牛客可以在线调试
第一题:字符串反转
第二题:二叉树反序列化+中序遍历
写完代码还没来得及调试就让先讲思路,然后就结束了。。。
三面(经理面,30min)
1.自我介绍
2.项目负责的模块占整个项目的百分之多少
3.负责的模块难点在哪
4.团队中和别的同学发生过意见不合的情况吗?如何解决的?
5.进程线程区别
6.进程的状态和转换条件?
7.输入一个网址后跳转到目标网页过程中用了哪些协议?DNS解析分类?ARP解析过程?
8.创建进程用到了哪些函数?答了fork,vfork,问了这俩区别
9.对测试的看法?讲了测试具体要承担的职业,让继续说,又说了测试需要具备的能力,还让继续,又说了测试和开发沟通的问题
10.为什么做测试?怎么学习测试的?学习了哪些东西?
11.设计测试用例的方法?
12.测试用例要素
13.可以实习吗?具体时间?
14.家是哪的?父母对我去北京工作的看法?
15.手里有哪些offer?美团和这些offer之间我选择哪个?
16.单身吗?
最后再吐槽一句,我不服,哈哈哈,因为美团是我最想去的公司,本来以为挺稳的,结果就这么莫名其妙挂了,还难过了一整天,后来他们来武汉面试的时候本来约了一个同学跟他一起去霸面的,结果前一天晚上百度约了3面,我就没有去,面完百度回来我就不想去霸面了,此处不留爷自有留爷处,哈哈
四、滴滴(校招批笔试,现场3轮技术+1轮hr)
滴滴面完没有写面经,我就大概回忆一下。
一面:50min
1、自我介绍
2、介绍项目,问了项目的一些细节(主要考察语言表达能力和思维清晰度)
3、针对项目设计测试用例
4、C++内存对齐,给了俩结构体例子让我求出占用内存大小
5、C++构造函数、拷贝构造函数和赋值运算符的应用,给了俩代码让我指出调用了哪个构造函数
6、平衡二叉树是什么?给8min手写平衡二叉树代码
忘了。。。
二面:40min
1、自我介绍
2、不用加减法交换两个整数值
3、写代码:把hello world转换为world hello(剑指offer原题)
4、0号进程和1号进程
5、智力题:100块钱买鸡,公鸡5块,母鸡2块,小鸡5毛,100块钱全部花完的前提下给出所有购买方案
6、写代码:实现STL的auto函数
7、c++ volatile关键字的作用
忘了。。。
三面:40min
三面是总监面,主要讲了项目,然后给了我一个实际的场景,让我想办法解决问题
HR面:20Min
继续套路。。。然后我还被套进去了
五、头条(内推笔试,3轮视频技术面,hr面还没挨到我)
依旧是靠回忆写面经,哈哈哈
一面:40min
1、自我介绍
2、写代码:N个数,有2个数出现了1次,其他数都是出现了1次,找出这2个数(剑指offer原题)
3、HTTPS了解吗
4、将一个HTTP数据包升级为HTTPS后,我如何设计测试用例
5、数据库索引类型
6、数据库删除表数据操作,答了delete和trancate。删除表操作?答了drop,然后问了这三个的区别
7、写了一个sql查询语句
8、TCP三次握手和四次挥手过程,挥手为啥要4次
9、shell用过吗?问了几个指令,让写出杀死错误日志中的进程的脚本代码
忘了。。。
二面:40min
1、自我介绍
2、写代码:非递归实现二叉树的镜像
3、给了几个数据库的表,写sql
忘了。。。
三面:50min
1、自我介绍
2、写代码:找出字符串中的驼峰字符(badcan,第一个a和第二个a就是驼峰),删除驼峰之间的字符
3、HTTPS了解吗
4、将一个HTTP数据包升级为HTTPS后,我如何设计测试用例(-_-||拿的是同一套面试题吗)
5、输出www.baidu.com后,从数据包走向、协议和前端发生的一些事情等方面讲一下
6、假设你是百度的工作人员,四川地区人民反应他们上不了百度主页,你将从哪些方面排查?
忘了。。。
面完后hr打电话说面试通过,10月中选前hr面。
六、百度(秋招笔试,现场3轮技术面)
一面:50min
1、自我介绍
2、写代码:字符串最长上升子序列
3、针对刚才的代码设计测试用例
4、写代码:判断链表是否有环
5、针对刚才的代码设计用例
6、给2个表,用sql的连接和嵌套两种方式写sql语句
7、测试电梯
忘了。。
二面:45min
1、自我介绍
2、写代码:实现memcpy函数
3、针对刚才的代码设计测试用例
4、写代码:字符串匹配的,具体不太记得了
5、针对刚才的代码设计测试用例
6、进程间通信方式
7、TCP和UDP区别,应用场景
8、为啥做侧开?优势是啥?
忘了。。。
三面:50min
1、自我介绍
2、问了一些性格方面的问题,还有项目中遇到问题和冲突如何解决的
3、写代码:给了个实际场景,设计算法然后写出来,不是很难,很快搞定,描述起来太麻烦我就不说了
4、10亿本书,如果想知道某个单词在哪些书中出现过,如何设计数据结构和算法?
5、测试两部电梯
忘了。。
七、电信IT研发中心(笔试,现场2轮技术+1轮hr电面)
岗位后端开发
一面:
1、自我介绍
2、C++指针和引用区别
3、C++ static关键字
4、C++ const关键字
5、C++ 类中一个函数可以同时用static和const修饰吗
6、数据库where和having区别
7、输入一个网址后发生了什么
8、HTTP包头
9、HTTPS了解吗
10、UML了解吗
忘了。。。
二面:
1、自我介绍
2、C++ 编程的时候都需要注意哪些问题?
3、C++ 内存分配方式
4、项目
忘了。。。
八、腾讯(秋招笔试,现场2轮技术+1轮hr)
一面:40min
1、自我介绍
2、实现strcpy函数(之前看了源码没考虑内存重叠,所以我写的时候也没考虑,然后被怼-_-||)
3、OSI七层模型(忘记会话层和表示层具体干嘛的了,大概按我的理解说了一下表示层作用)
4、了解jemter底层原理吗?我说不了解,但是我可以说说我的理解,然后说了一堆
5、为啥做侧开?优势?为啥去深圳?诸如此类的一些问题
忘了。。。
一面是个leader,全程面无表情怼我,搞得我好紧张,但是我还是全场面带微笑扛下来了,结束的时候让我问问题,本来觉得应该是挂了,但是出于礼貌还是问了两个问题。后来竟然过了,汗。
二面:40min
1、自我介绍
2、写代码:快排。问了时间复杂度和稳定性
3、TCP握手流程
4、TIME WAIT了解吗
5、TCP劫持了解吗
6、上网的时候界面有时候会弹出广告,你觉得是什么原因?
7、socket编程的流程
8、数据库索引底层原理
忘了。。。
HR面:45min
腾讯的hr面感觉快赶上某为的面试了,性格、家庭、兴趣爱好巴拉巴拉的全都问,都是套路,但是一不小心还是会被套进去。
腾讯今年的面试很奇怪,面的很简单,看了其他搞后台开发的同学的面经感觉也都挺基础,这是要扩招?
关于测试&测试开发&开发
前段时间有个同学问我投的都是什么岗,我说侧开,他说那你岂不是已经一堆offer了。。。我当时挺无语,感觉搞开发的同学特别看不起侧开,感觉侧开就是给他们打杂的没什么技术含量。就我了解,百度的侧开不仅仅是开发测试工具和平台,还要跟业务结合做一些开发的工作,其他公司好像基本都是开发工具和脚本。在我面试的这些公司里,基本都是以开发的标准在面侧开,测试的东西反而比较少,代码该写的还是要写,算法该问的还是要问,从编程语言,数据结构,数据库,网络到linux,我不觉得这些知识哪一项是侧开可以不掌握的,不知道有些看不起侧开的同学是什么情节,侧开的开发工作确实会比开发少一些,但是不论是面试还是知识广度深度上都不会亚于开发的。
对于测试工程师,主要是做功能测试,所以相对较轻松。
关于秋招准备
我读研期间主要是做理论研究,今年三月份才看完c++、数据结构和网络,找实习的时候投的都是开发岗,奈何基础太差,没找到。七月份注意到测试开发这个岗位,分析了一下觉得更适合我,所以开始看了一些测试的书籍和视频,自学了软件测试工具jemeter,但是平时看书主要还是按开发的要求在准备,刷题主要是剑指offer,在牛客刷了2遍,每次面试前我都会再过一遍。
关于内推or校招
就今年的形式来看,内推开始的特别早,很多人都参加了内推,估计内推就占了很多坑,在准备的还可以的前提下我建议参加内推,有的公司内推不过还可以秋招,但是感觉几率很小了。但是内推存在的问题是,开始的早,准备可能不够充分,另一方面,远程面试的效果会比现场面差,所以如何取舍还是要看自己。
关于面试套路
1、问到会的东西,一定要慢点说(虽然我到现在也没学会,面试的时候总是会忘记这点),可以适当拓展,把自己知道的相关的都说出来,把面试官往会的地方引,不要被牵着鼻子走,不然。。。你懂得。
2、遇到不会的,如果是偏底层的问题,大家了解的其实都不多,可以跟面试官说说自己的理解,如果是表层的东西,不会的就直接说不会,不要瞎掰。
3、面试的时候一定要表现的自信!这点特别重要!有时候回答完面试官会反问确实是这样吗?这个时候如果比较确定就一定要自信的说确定!
4、面完让问问题的时候一定要多问岗位相关的,显得你好学!
5、hr面主要考察你的稳定性、积极性和性格,要小心一些,表现的积极主动乐观一些,不然容易被套路,别问我为什么。。。
6、关于现场写代码,一般不会很难,基本都是剑指offer的题目,十分钟以内可以搞定,实在不会的,就按笨办法写,然后面试官会引导你的。还有需要注意的就是,想到一个方法,不管好不好,都要说出来,表明你在主动思考,抛砖引玉,面试官会继续引导你的。
今天先写到这,后期想到别的东西我会来补充,祝大家顺利~~~