web项目
说说epoll与select不同
select基于轮询机制,epoll基于通知机制,直接通知发生IO事件的fd,select需要在内核去和用户去不断拷贝fd_set, epoll采用共享内存机制,不需要,epoll内核数据结构用的是红黑树,效率更高。
能说说红黑树吗
高度平衡的二分搜索树,有两种节点,一种节点是红色,另一种节点是黑色。
应用红黑树的场景(STL中map与set,面试官补充linux中线程调度用的红黑树)
说说线程调度算法
1、先来先服务(FCFS)
2、最短作业优先(SJF)
3、基于优先权的调度算法(FPPS)
4、时间片轮转(RR)
5、多级队列调度(Multilevel feedback queue)
说说进程通信的方式
说说malloc和new的区别
Malloc返回值及其含义
返回void*类型的指针
知道跳表吗 (redis 底层数据结构中涉及到跳表,所以面试中也会被问到跳表)
跳表是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表。
为什么Redis选择使用跳表而不是红黑树来实现有序集合?
首先,我们来分析下Redis的有序集合支持的操作:
1)插入元素
2)删除元素
3)查找元素
4)有序输出所有元素
5)查找区间内所有元素
其中,前4项红黑树都可以完成,且时间复杂度与跳表一致。
但是,最后一项,红黑树的效率就没有跳表高了。
在跳表中,要查找区间的元素,我们只要定位到两个区间端点在最低层级的位置,然后按顺序遍历元素就可以了,非常高效。
而红黑树只能定位到端点后,再从首位置开始每次都要查找后继节点,相对来说是比较耗时的。
此外,跳表实现起来很容易且易读,红黑树实现起来相对困难,所以Redis选择使用跳表来实现有序集合。
说说tcp udp
传输层协议,tcp有连接,udp无连接
知道的锁(乐观锁悲观锁读写锁自旋锁)
项目中用的http哪个版本(1.1)
http1.0和1.1的区别
主要回答出长连接,短连接即可
有实现http1.1的组块化(chunk)吗(没有)
然后叫回去把项目代码发到面试官邮箱。
(项目源代码建议上传github)
后面进去实习了一个月,觉得实习离学校太远每天来回两个小时辞职了。然后8月中投了深信服优招。由于实习过,所以直通综面。一开始自己不知道,面完面试官说时有点意外。
为什么服务器项目中用线程池
提高并发效率
http1.0/1.1/2.0
Hash 表
删除最后一个元素容易
当天下午收到了第二天hr面的邮件
再说算法,由于我遇到的手撕代码问题不是很困难,大概剑指offer的难度,遇到过的题目有:
67891234这样的数组中找到下降点
二分查找,找分界点
异或运算?
简单题目, 一个栈入队,另一个栈出队
判断一个字符串中出现的括号是否相匹配
用栈
发散性问题,可能要积累一些分布式的理论,积累一些经验,我遇到的问题有:
区别一:
路由器可以给局域网自动分配IP,虚拟拨号。交换机则只是用来分配网络数据的。
区别二:
路由器可以把一个IP分配给很多个主机使用,这些主机对外只表现出一个IP。交换机可以把很多主机连起来,这些主机对外各有各的IP。
区别三:
交换机工作在中继层,根据MAC地址寻址,不能处理TCP/IP协议。
路由器工作在网络层,根据IP地址寻址,可以处理TCP/IP协议。
ping命令主要检查网络通不通,采用ICMP协议,属于网络层
域名系统 DNS (使用UDP)
1. 层次结构
域名服务器可以分为以下四类:
(1) 根域名服务器:解析顶级域名;
(2) 顶级域名服务器:解析二级域名;
(3) 权限域名服务器:解析区内的域名;
区和域的概念不同,可以在一个域中划分多个区。图 b 在域 abc.com 中划分了两个区:abc.com 和 y.abc.com
因此就需要两个权限域名服务器:
(4) 本地域名服务器:也称为默认域名服务器。可以在其中配置高速缓存。
2. 解析过程
主机向本地域名服务器解析的过程采用递归,而本地域名服务器向其它域名服务器解析可以使用递归和迭代两种方式。
迭代的方式下,本地域名服务器向一个域名服务器解析请求解析之后,结果返回到本地域名服务器,然后本地域名服务器继续向其它域名服务器请求解析;而递归地方式下,结果不是直接返回的,而是继续向前请求解析,最后的结果才会返回。
域名系统 DNS (使用UDP)
1. 层次结构
域名服务器可以分为以下四类:
(1) 根域名服务器:解析顶级域名;
(2) 顶级域名服务器:解析二级域名;
(3) 权限域名服务器:解析区内的域名;
区和域的概念不同,可以在一个域中划分多个区。图 b 在域 abc.com 中划分了两个区:abc.com 和 y.abc.com
因此就需要两个权限域名服务器:
(4) 本地域名服务器:也称为默认域名服务器。可以在其中配置高速缓存。
2. 解析过程
主机向本地域名服务器解析的过程采用递归,而本地域名服务器向其它域名服务器解析可以使用递归和迭代两种方式。
迭代的方式下,本地域名服务器向一个域名服务器解析请求解析之后,结果返回到本地域名服务器,然后本地域名服务器继续向其它域名服务器请求解析;而递归地方式下,结果不是直接返回的,而是继续向前请求解析,最后的结果才会返回。
从100回答到500
数据库:
JAVA:
多线程:
JAVA基础:
spring相关:
设计模式:
操作系统:
算法:
session在服务器,cookie在客户端
string list, hash,set,zset
HTTP 明文,HTTPS加密
GET参数在url,POST参数在后面
B+ 树数据都存放在叶子节点,非叶子节点只存放索引,B+树更少得磁盘IO
B+ 树
DNS,TCP, HTTP
ip到mac地址
剑指offer原题
岗位:服务器开发工程师
1、你在项目在遇到过最困难的事。
2、操作系统、网络原理、编译原理。。。你最擅长哪个?(网络?)
3、浏览器的地址栏里输入一个url,点一下回车,会发生什么?
(1)浏览器怎么得到url?
(2)DNS解析是发送整个url吗?
发送域名
(3)DNS解析详细过程。
(4)TCP三次握手之前需要什么?
(5)ARP解析过程。
(6)ip怎么寻址?
(7)TCP第三次握手的作用是什么?
(9)TCP连接建立之后呢?
发送数据,滑动窗口机制,发送接收
4、算法题:单链表,翻转n-m段链表。
5、算法题:给出有序数组和target求距离target最小的位置(min distance index)。(二分查找)
1、自我介绍。
2、重点介绍实习内容以及你做的工作内容?(详细)
3、人员权限管理模块怎么设计?
4、sql题:
student:id, name, age
student_score: id,student_id, course_id, score
平均成绩前三的student_id, name
5、数据库索引的数据结构。
6、b加树和b树的区别。
7、为什么索引用b加树而不用红黑树?
8、死锁的条件。
9、如何设计来避免死锁。
10、算法题:求连续子数组最大和以及对应子数组的首尾坐标。
1、自我介绍。
2、重点介绍学校项目的内容。
3、介绍自己做的内容(详细)。
4、画图:3个后端模块画项目流程图(详细)。
5、讲后端流程中每一部分怎么实现。
6、各部分怎么保证多线程安全。
7、Redis一致性怎么保证。
8、Redis分布式锁的原理。
9、你所了解的分布式一致性算法。
10、画图:深度学习模块项目流程图(详细)。
11、讲深度学习流程中每一部分的含义。
12、Python程序是怎样定时运行的。
13、nlp和cv数据预处理各自的流程(实验室课题不便透漏,用大方向nlp和cv代替)。
14、nlp和cv各用了什么模型。
15、结果返回的实效性问题。
16、项目有没有分布式部署。
17、如果要部署怎么部署。
18、设计题:有一个二维坐标系上有10亿个点,给定一个圆,如何快速得出哪些点在圆中(返回点集)?
这大概是我发的最长的一个面经帖子了,新鲜的凉经最适合拿来攒人品。
直接一点吧:
1.自我介绍
2.说说B+树和B树的区别,优缺点等?
3.聊聊Spring,主要IOC等等
4多线程JUC包下的一些常见的类,比如CountDownLatch、Semaphore等
5.锁的概念,锁相关的关键字,volatile,synchronized。还比较了ReentrantLock与synchronized。
6.你了解哪些收集器?CMS和G1。详细谈谈G1的优点?什么时候进行Full GC呢?
7.Spring中涉及的一些设计模式
8.算法题:无序数列中求第k大的数(维护最小堆,然后依次遍历,与堆顶比较) topK 问题
9.MySQL创建索引的原则,好处
10. 怎么实现一个线程安全的计数器?加锁
1. 设计模式:讲了单例,工厂方法,抽象工厂,策略模式,观察者模式,代理模式,还顺便讲了下spring动态代理的实现原理
2. 线程池有哪些参数?分别有什么用?如果任务数超过的核心线程数,会发生什么?阻塞队列大小是多少?
3. HashMap的底层数据结构 数组+链表,当链表长度大于8变为红黑树
4. 红黑树的具体结构及实现,红黑树与查找树的区别体现
5. 接着聊ConcurrentHashMap,底层实现
6. HashMap哈希函数的认识,JDK1.8采用的hash函数
7. 数据库索引,索引底层的实现,B+树的结构以及与普通查找树的优点
9. TCP三次握手四次挥手,四次挥手过程中服务端的哪几种状态,哪几种包
10. 已经有一个查询好友的接口,设计一个微信朋友圈,可以实现发表朋友圈,添加评论,查看评论等功能。主要是设计数据结构
交代:南京工信部211,本硕机械。技术栈c++/python,单片机+GUI开发+服务端开发+大数据平台拿过top10(非天池,非kaggle)
牛客网大佬很多,所以犹豫了很久要不要发这条,但是为了纪念8月,还是码了一点字,目前有点丧,希望9月可以重新振作。
华为实习(一面,简单):
1.运行时多态
2.手写快排
3.手写双重锁singleton
4.优化hash
5.快慢指针
6.图的环(BFS实现)
华为实习(二面,简单):二面五分钟内,问我女朋友在哪里。问我南京这城市咋样。问我为什么想来华为
地平线实习笔试:笔试现场笔试1小时:6个简答题,3个编程题,3个智力题(简单,基础题)
地平线实习一面:在公司面,首先会聊你的笔试题,他会过一遍,然后问几个感兴趣的点。 然后将近一小时,聊项目,非常的细致,聊比赛。
地平线实习电话面:很快,20分钟,没有聊什么太深入的东西。Hr后来说一面是自己的boss,应该是技术面没问题,二面走形式了。
字节跳动(凉经):两次面试经历,第一次面的java面试官毫无兴趣。第二次面的c++,确实看出来了一些问题。简单的概念与一些应用都是阔以的,但是拓展题明显力不从心。问我怎么检查内存泄漏:说了用过memcheck和mfc查看,接下来问我你有没有想过memcheck里是如何定位错误行的。当时一脸蒙蔽,遂卒。 图论的一些优化和扩展:这个没话说,确实图论了解一般,还好没写华为软挑的经历,估计要被喷死。
中兴(一面,纯聊天,很简单):1.自我介绍 2.pclint检查出来过什么错误 3.union和struct区别 5.多线程细节 6.socket连接池实现 7.mvc设计模式 8.mfc用过哪个窗口 9.网卡是七层模型的哪一个 每个问题都很简单,所以很顺畅,两位面试官全程沉默看简历,十分钟不到让我走了。
(二面):LT和ET的区别?2.代码量 3.闲聊几句,然后就欢迎加入了
华为FX一面(如果FX过了,大概率不找了,但是今年8月华为有政策变动,约总裁面路上遇到华为8月1改革,要重新面三轮):
1.简单数据结构:链表和哈希 。问猜猜底层是用什么数据结构分配的内存,讲一下你自己设计的话怎么优化(深入,恰好命中目前内存实际分配方式)
2.华为V8架构优点缺点,与现在急需要突破的问题(深入)
3. 二三层转发,ARP等业务知识
4.目前的代码规范有什么不妥(深入)
5.你觉得一个好的代码应该是怎样的
6.如何攻破华为现在的系统,有什么漏洞(深入----回答的最不好的问题)
7.快排,树的四种遍历
8.关于对llt架构整改的认识,对设计模式的认识(深入)
9.代码量,平时的爱好
实习所做内容分享(因人而异吧),浏览器输入网址所有的过程以及使用到的所有协议,Os,内存分配伙伴算法,服务器端的LT,socket,http,tcp,epoll,select(项目中如何实现的),LT和ET选了哪个,原因,效果,进程间通讯如何实现,粘包问题的解决方式,简单数据结构,Dp爬楼梯问题
1.如何在linux里保证一个程序只开了一个进程
2 . 有10000台服务器,如何判断他们有哪些监听80端口(不能只用connect)
1.手写快排
2.c++的各种基础
3.实习经历
4.对公司游戏的了解
5.介绍自己的项目
6.数据库索引,底层实现
1.手写链表成环问题判断(快慢指针)
2.c++11新特性的提问
3.项目实现细节,多线程方面如何处理
4.对opencv的了解程度,视觉方面的
5.数据库事务
6.linux的了解
1.手写一个大数如何找到最大的3位数约数
2.手写二维数组翻转90度
3.设计模式使用经历
4.介绍一下比赛用过的xgboost,和数据处理方面的方法,以及建模思路
5.实习经历遇到的最大困难
6.多进程,多线程联调遇到的困难
7.做过的底层有关的问题
8.opencv的了解,讲清楚用opencv做过的项目
浦发银行(笔试三道题+面试1轮):笔试3道题很简单,基本平均一道题10分钟不到吧(例如问你三位数,四位数,五位数有几个奇数…把它print出来)面试:一人10分钟,形式六个面试官,聊天+问一个算法题
疯狂游戏二面(通过):差不多一个小时视频面,技术专家,问的计算机基础知识相当多(结束过面试官有说,公司重点考察计算机基础,c++基础等),也有一些提升题,个人感觉难于一面。
疯狂游戏三面(通过):对公司游戏的看法,提升,玩游戏多不多,一般玩什么,各有什么优点
地平线校招(三面通过):问的还是比较深入的,对于服务器,高并发,多线程,多进程,c++的知识等电话面。没有回答上来的(共享内存底层什么结构实现)
美团一面(转岗了):日常os,进程,线程,c++,python,sql。视频面试3个手写代码(翻转链表,回文链表,判断是不是完全二叉树)+1道概率题(54张扑克牌分成3堆,大小王同时在一堆的概率)
地平线校招(四面通过):北京总部面,通过。
依图校招(一面通过):时间大约一小时,以手写代码为主,很少问技术问题
依图校招(二面没消息) :面的不好自己心里有数,手写一个leetcode hard题没写出来,面试官也着急走,放弃了。
一、面试第 1 轮
1. linux 网络模型
2. b+树
3. 阻塞队列
4. redis 和 MongoDB 的区别。几个概念对比,还有底层实现。
5. 算法题: merge k sorted list,时间复杂度如何?
LC题目, 时间复杂度O(Nlogk)
6. HashMap 如果一直 put 元素会怎么样?hashcode 全都相同如何?equals 方法都相同
扩容
7. ApplicationContext 的初始化过程?初始化过程中发现循环依赖 Spring 是如何处理的。
8. GC 用什么收集器?收集的过程如何?哪些部分可以作为 GC Root?
9. Volatile 关键字,指令重排序有什么意义?
10.synchronied 怎么用?
11.并发包里的原子类有哪些,怎么实现?cas 在 CPU 级别用什么指令实现的?
12.Redis 数据结构有哪些?如何实现 sorted set?这种数据结构在极端情况下可能有什么
问题?二叉平衡树?
13.系统设计题:一个推送场景,50 条内容,定时推送,先推 5%用户,一段时间后再找出
效果最好的几条,推给所有用户。设计相关库表,系统模块, 需要可以落地,有伪代码
14.MySql 索引是什么数据结构?B tree 有什么特点?优点是什么?
15.慢查询怎么优化?
16.项目:cache 设计,MQ 丢失消息,RPC 使用场景。各部分职责,有哪些优化点。
17.ThreadLocal 使用场景
18.Redis 回收和备份
19.项目设计问题——主要是针对项目找漏洞,然后给出优化方案
20.遇到的坑,怎么解决,后续总结。
二、面试第 2 轮
1. 那些问题对你挑战最大?
2. JDK 1.8 ConcurrentHashMap 做过什么改进?HashMap 死锁?
3. 标记的时候怎么找出栈上的 GC Root?说出一种可能的方案,存在什么问题?
4. 字节码有了解过吗?
5. 本地缓存怎么优化空间?(提出 BitMap)BitMap 可行吗?怎么验证可行性?如果不
可行,怎么证伪?
6. 其他语言有了解过吗?Scala 的集合有什么特性?python 有什么高级特性?
7. 怎么学习新技术?哪些是基础技术?
8. 在部门中是什么角色定位?
9. JDK 1.8 比前一个版本有哪些改进?
10. ParNew 收集过程,如何调优 ParNew?如何减少 full gc?调大 YoungGen 有什么好处
坏处?
11. OpenAPI
12. 平衡二叉树13. 业务逻辑
14. MySQL
15. 服务设计题
16. web 架构设计
17. Pack
18. http 协议
19. 爬虫
20. Java Agent
21. Zookeeper
22. LoadBalance
23. 分布式 ID
24. Nginx
25. Cookie
26. Session
27. GC
28. 手写 LRU 缓存
29. 将现有线性存储结构改成环形结构
30. Redis IO 模型
31. MQ 架构对比
32. 各种缓存 memcache,MongoDB,EhCache,Guava,Caffeine 等等,使用场景
33. 数据库乐观锁悲观锁。在 JDK 和其他中间件的体现。
34. 线程池,核心参数,扩容原理,使用注意点
35. 数据库主从同步,延迟
36. 数据库和缓存一致性问题,出现的场景,解决方案
37. Spring IOC AOP
38. 一致性哈希算法
39. RPC 服务发现与注册
40. 服务提供方不稳定,频繁变动如何提升自身稳定性
三、面试第 3 轮—HR
1. 离职原因
2. 学习习惯
3. 兴趣爱好
4. 为什么选择本公司
5. 本人的优缺点
6. 唠家常
1.多线程和多进程的区别(重点 必须从cpu调度,上下文切换,数据共享,多核cup利用率,资源占用,等等各方面回答,然后有一个问题必须会被问到:哪些东西是一个线程私有的?答案中必须包含寄存器,否则悲催)!
1)进程数据是分开的:共享复杂,需要用IPC,同步简单;多线程共享进程数据:共享简单,同步复杂
2)进程创建销毁、切换复杂,速度慢 ;线程创建销毁、切换简单,速度快
3)进程占用内存多, CPU利用率低;线程占用内存少, CPU利用率高
4)进程编程简单,调试简单;线程 编程复杂,调试复杂
5)进程间不会相互影响 ;线程一个线程挂掉将导致整个进程挂掉
6)进程适应于多核、多机分布;线程适用于多核
线程所私有的:
线程id、寄存器的值、栈、线程的优先级和调度策略、线程的私有数据、信号屏蔽字、errno变量
2. 多线程锁的种类有哪些?
a.互斥锁(mutex)b.递归锁 c.自旋锁 d.读写锁
3. 自旋锁和互斥锁的区别?
当锁被其他线程占用时,其他线程并不是睡眠状态,而是不停的消耗CPU,获取锁;互斥锁则不然,保持睡眠,直到互斥锁被释放激活。
自旋锁,递归调用容易造成死锁,对长时间才能获得到锁的情况,使用自旋锁容易造成CPU效率低,只有内核可抢占式或SMP情况下才真正需要自旋锁。
4.进程间通信和线程间通信
1).管道 2)消息队列 3)共享内存 4)信号量 5)套接字 6)条件变量
5.多线程程序架构,线程数量应该如何设置?
应尽量和CPU核数相等或者为CPU核数+1的个数
6.什么是原子操作,gcc提供的原子操作原语,使用这些原语如何实现读写锁?
原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch。
7.网络编程设计模式,reactor/proactor/半同步半异步模式?
reactor模式:同步阻塞I/O模式,注册对应读写事件处理器,等待事件发生进而调用事件处理器处理事件。 proactor模式:异步I/O模式。Reactor和Proactor模式的主要区别就是真正的读取和写入操作是有谁来完成的,Reactor中需要应用程序自己读取或者写入数据,Proactor模式中,应用程序不需要进行实际读写过程。
Reactor是:
主线程往epoll内核上注册socket读事件,主线程调用epoll_wait等待socket上有数据可读,当socket上有数据可读的时候,主线程把socket可读事件放入请求队列。睡眠在请求队列上的某个工作线程被唤醒,处理客户请求,然后往epoll内核上注册socket写请求事件。主线程调用epoll_wait等待写请求事件,当有事件可写的时候,主线程把socket可写事件放入请求队列。睡眠在请求队列上的工作线程被唤醒,处理客户请求。
Proactor:
主线程调用aio_read函数向内核注册socket上的读完成事件,并告诉内核用户读缓冲区的位置,以及读完成后如何通知应用程序,主线程继续处理其他逻辑,当socket上的数据被读入用户缓冲区后,通过信号告知应用程序数据已经可以使用。应用程序预先定义好的信号处理函数选择一个工作线程来处理客户请求。工作线程处理完客户请求之后调用aio_write函数向内核注册socket写完成事件,并告诉内核写缓冲区的位置,以及写完成时如何通知应用程序。主线程处理其他逻辑。当用户缓存区的数据被写入socket之后内核向应用程序发送一个信号,以通知应用程序数据已经发送完毕。应用程序预先定义的数据处理函数就会完成工作。
半同步半异步模式:
上层的任务(如:数据库查询,文件传输)使用同步I/O模型,简化了编写并行程序的难度。
而底层的任务(如网络控制器的中断处理)使用异步I/O模型,提供了执行效率。
8.有一个计数器,多个线程都需要更新,会遇到什么问题,原因是什么,应该如何做?如何优化?
有可能一个线程更新的数据已经被另外一个线程更新了,更新的数据就会出现异常,可以加锁,保证数据更新只会被一个线程完成。
9.如果select返回可读,结果只读到0字节,什么情况?
某个套接字集合中没有准备好,可能会select内存用FD_CLR清为0.
10. connect可能会长时间阻塞,怎么解决?
1.使用定时器;(最常用也最有效的一种方法)
2.采用非阻塞模式:设置非阻塞,返回之后用select检测状态。
11.keepalive 是什么东西?如何使用?
keepalive,是在TCP中一个可以检测死连接的机制。
1).如果主机可达,对方就会响应ACK应答,就认为是存活的。
2).如果可达,但应用程序退出,对方就发RST应答,发送TCP撤消连接。
3).如果可达,但应用程序崩溃,对方就发FIN消息。
4).如果对方主机不响应ack, rst,继续发送直到超时,就撤消连接。默认二个小时。
12.socket什么情况下可读?
1.socket接收缓冲区中已经接收的数据的字节数大于等于socket接收缓冲区低潮限度的当前值;对这样的socket的读操作不会阻塞,并返回一个大于0的值(准备好读入的数据的字节数).
2.连接的读一半关闭(即:接收到对方发过来的FIN的TCP连接),并且返回0;
3.socket收到了对方的connect请求已经完成的连接数为非0.这样的soocket处于可读状态;
4.异常的情况下socket的读操作将不会阻塞,并且返回一个错误(-1)。
13.udp调用connect有什么作用?
1).因为UDP可以是一对一,多对一,一对多,或者多对多的通信,所以每次调用sendto()/recvfrom()时都必须指定目标IP和端口号。通过调用connect()建立一个端到端的连接,就可以和TCP一样使用send()/recv()传递数据,而不需要每次都指定目标IP和端口号。但是它和TCP不同的是它没有三次握手的过程。
2).可以通过在已建立连接的UDP套接字上,调用connect()实现指定新的IP地址和端口号以及断开连接。
14. socket编程,如果client断电了,服务器如何快速知道?
使用定时器(适合有数据流动的情况);
使用socket选项SO_KEEPALIVE(适合没有数据流动的情况);
1)、自己编写心跳包程序,简单的说就是自己的程序加入一条线程,定时向对端发送数据包,查看是否有ACK,根据ACK的返回情况来管理连接。此方法比较通用,一般使用业务层心跳处理,灵活可控,但改变了现有的协议;
2)、使用TCP的keepalive机制,UNIX网络编程不推荐使用SO_KEEPALIVE来做心)跳检测。
keepalive原理:TCP内嵌有心跳包,以服务端为例,当server检测到超过一定时间(/proc/sys/net/ipv4/tcp_keepalive_time 7200 即2小时)没有数据传输,那么会向client端发送一个keepalive packet。