阿里3.26Java研发工程师一面面经

需要注意的点:

  • 不要说废话
  • 不要给自己挖坑,不会的点不要说
  • 不要说太多,点到为止,让面试官提问
  • 上来先自我介绍
  • 问项目和基础的知识点
  • 问对哪方面感兴趣,有没有读技术博客的习惯
  • 场景题,如何保证聊天信息的发送不会重复,确认送达
  • 自己做过的时间最长的一件事?在这其中遇到的最大的困难?如何解决的
  1. 讲一下二叉排序树、平衡二叉树
  2. 讲一下C++和Python之间的区别(因为我提到了自己会这两种语言)
  3. 讲一下对OSI七层网络模型的理解。。。详细讲一下哪几层
  4. 详细介绍其中一个层,比如物理层?(主要是传输介质?是。。)还能想到别的嘛?

开放性问题

  1. 对于网络聊天的想法?消息是怎么发送过来的?对异常情况怎么处理(到达、重复)?
  2. 网络聊天是怎样一个流程?端到端的一个流程?

寻找位置、确认身份、建立连接、发送消息。

  1. 端到端是可以直接建立连接嘛? 不是,需要经过服务器转发。
  2. 服务器具体是怎样处理的?解包,转发。
  3. 会不会存在发送消息丢了,重发的情况,比如客户端收到两条?不会,网络协议会保证可靠性和不重传。主要是通过传输层和应用层来保证。
  4. 通信怎么判别消息是否重复?序列号机制。 其他还有吗? 想不到了。
  5. 了不了解网络爬虫? 了解,爬虫是搜索引擎的基础,从一个网页遍历到另一个网页,建立索引库。
  6. 有没有做过网络爬虫的应用?做过简单的应用,模拟登录豆瓣网、知乎。
  7. 做的初衷是什么?是有需要还是好奇? 出于好奇。
  8. 爬到数据之后有没有做别的处理? 没有。

按照实际和日常来聊

  1. 分享一些开始不是很擅长但是后来居上的例子? 运动,高中不擅长,大学坚持运动
  2. 你觉得由原来的不擅长到擅长最重要的原因是什么呢?有达到你的预期吗? 时间上的积累,速成很难,不断地练习,反思。
  3. 你做的最久的一件事?有没有遇到什么困难,怎么克服的?hhh整理的过程中突然想到了吃饭和睡觉。 我回答的学英语,从初中到大学,小有成就。困难,很难坚持下来;方法,不断设定新的目标,考试。
  4. 有更实际一些的困难吗?实际的困难和解决方法? 闭门造车,不知道自己的进度,算吗? 按照你自己的理解就好啦。。。 多交流,多找参照物,寻找反馈。
  5. 学习之余的生活会不会看技术资料和技术博客? 看的比较少,学啥看啥。先看工程,再看深度精进。
  6. 在技术领域方面有没有比较感兴趣的?或者说深入了解过哪方面? 网络,自己对翻墙有需求,所以了解过,从shadowsock到trojan。
  7. 研究过但是没有开发过? 是的。
  8. 你觉得难点会在什么地方? 首先确定框架,首先选择协议,然后是实现细节。 主要是地基要打好,否则很容易被封。
  9. 原理你了解到了多深的程度?仅仅是了解,扫了几眼。
  10. 能不能分享作为团队的组织者或者领导者的经历? 本科期间的大创。首先拉人,然后分工,在项目进行过程中调整分工,做好利益分配。
  11. 项目中最复杂的事情,最复杂的任务? 这部分答得太差,答不到重点上。
  12. 有具体点的例子吗? 确定任务计划书的过程,开会调研。
  13. 在本科、硕士期间有没有突出的成绩,比如竞赛或者论文?
  14. 在知名比赛、科技公司、实验室有没有突出的技术贡献?发表过专利?只发表过一篇论文。
  15. 论文发表在哪里?论文的内容?
  16. 你有没有什么想了解的?
  17. 您最近在做什么工作? 支付业务,服务端的整体链路。
  18. 对我有什么建议?面试按照正常发挥就OK了,你的表现是比较自然的,把最真实的自我表现出来就OK了。不只看技术能力,会看一些综合情况。会看学校的情况,个人的一些特质。
  19. 如何提高? 不是科班出身,如果真的有兴趣,可以多深挖,研究一下。有兴趣的,多坚持一下。不一定用到再去看,真的有兴趣就多看一点。

    3.28腾讯客户端开发面经

    开始自我介绍,问项目,然后问基础知识,操作系统,网络,C++这些,最后两道编程题。

冒泡排序的递归写法:

自己开始写的双层for循环的写法,自己开始写的神奇方法把自己和面试官都搞懵逼了,后来发现自己写的代码其实是有问题的,并不是冒泡排序(相邻两个数,比较交换),只是每次保证i位置元素最小,类似选择排序?

  1. #include <iostream>
  2. using namespace std;
  3. void bubble_sort(int arr[], int n){
  4. for(int i = 0; i < n; i++){
  5. for(int j = i; j < n; j++){
  6. if(arr[i] > arr[j]){
  7. swap(arr[i], arr[j]);
  8. }
  9. }
  10. }
  11. }
  12. int main() {
  13. int arr[] = {5, 4, 2, 3, 6};
  14. int n = 5;
  15. bubble_sort(arr, 5);
  16. for(int i = 0; i < n; i++){
  17. cout<<arr[i]<<endl;
  18. }
  19. }

然后在面试官的提示下改成了递归写法,去掉了一个for,一层一层递归,还是类似选择排序的方法。

  1. #include <iostream>
  2. using namespace std;
  3. void bubble_sort(int arr[], int i, int n){
  4. for(int j = i; j < n; j++){
  5. if(arr[i] > arr[j]){
  6. swap(arr[i], arr[j]);
  7. }
  8. }
  9. if( i < n ) bubble_sort(arr, i + 1, n);
  10. }
  11. int main() {
  12. int arr[] = {5, 4, 2, 3, 6};
  13. int n = 5;
  14. bubble_sort(arr, 0, 5);
  15. for(int i = 0; i < n; i++){
  16. cout<<arr[i]<<endl;
  17. }
  18. }

最后自己查了一下,这个才是真正的冒泡排序啊!比较相邻元素,大元素上冒,然后每次上边界-1

加一个flag判断,假如不需要排序了,直接退出即可

非递归写法

  1. #include <iostream>
  2. using namespace std;
  3. void bubble_sort(int arr[], int n) {
  4. for (int i = n - 1; i >= 0; i--) {//排序的上界,每次减1
  5. int flag = 0;
  6. for (int j = 0; j < i; j++) {
  7. if (arr[j] > arr[j + 1]) {
  8. swap(arr[j + 1], arr[j]);
  9. flag = 1;
  10. }
  11. if (!flag) return;
  12. }
  13. }
  14. }
  15. int main() {
  16. int arr[] = { 5, 4, 2, 3, 6 };
  17. int n = 5;
  18. bubble_sort(arr, 5);
  19. for (int i = 0; i < n; i++) {
  20. cout << arr[i] << endl;
  21. }
  22. }

递归写法, 上界要写成n-1,防止越界

  1. #include <iostream>
  2. using namespace std;
  3. void bubble_sort(int arr[], int n) {
  4. int flag = 0;
  5. for (int i = 0; i < n - 1; i++) {
  6. if (arr[i] > arr[i + 1]) {
  7. swap(arr[i + 1], arr[i]);
  8. flag = 1;
  9. }
  10. }
  11. if (!flag) return;
  12. if (n > 0) bubble_sort(arr, n - 1);
  13. }
  14. int main() {
  15. int arr[] = { 5, 4, 2, 3, 6 };
  16. int n = 5;
  17. bubble_sort(arr, 5);
  18. for (int i = 0; i < n; i++) {
  19. cout << arr[i] << endl;
  20. }
  21. }

实现双向队列,实现头尾插入或者删除

写队列,自己直接就想到了数组的方法,写完之后面试官就问如果超出容量怎么办;想了一会才想到采用链表的方法,真是太菜了。

然后在写的过程中发现对于类的定义和指针操作这些不熟练,边写边害怕是不是写错了。

  1. #include <iostream>
  2. using namespace std;
  3. class deque {
  4. struct Node {
  5. int num;
  6. Node* pre;
  7. Node* next;
  8. Node(int n) :num(n), pre(NULL), next(NULL) {
  9. }
  10. };
  11. struct Node* front;
  12. struct Node* back;
  13. public:
  14. deque(int num) {
  15. front = new struct Node(num);
  16. back = front;
  17. }
  18. void front_insert(int num) {
  19. struct Node* ptr = new struct Node(num);
  20. front->next = ptr;
  21. ptr->pre = front;
  22. front = front->next;
  23. }
  24. void back_insert(int num) {
  25. struct Node* ptr = new struct Node(num);
  26. back->pre = ptr;
  27. ptr->next = back;
  28. back = back->pre;
  29. }
  30. void front_delete() {
  31. struct Node* tmp = front;
  32. front = front->pre;
  33. front->next = nullptr;
  34. delete tmp;
  35. }
  36. void back_delete() {
  37. struct Node* tmp = back;
  38. back = back->next;
  39. back->pre = nullptr;
  40. delete tmp;
  41. }
  42. };
  43. int main() {
  44. deque q(-1);
  45. q.front_insert(2);
  46. q.back_insert(2);
  47. q.front_insert(4);
  48. q.back_insert(5);
  49. q.front_delete();
  50. q.back_delete();
  51. return 0;
  52. }

4.24微软技术支持工程师

总结:考察的点主要在经历、综合素质以及职业规划,专业知识主要考察TCP协议(之前邮件里提示过要看了)。
一面:

  1. 自我介绍
  2. 介绍一个主要的项目
  3. 在这个项目中遇到的最大困难,怎么克服的?
  4. 项目中的沟通协调问题?做的好的,做的不好地方?
  5. 介绍一下CS相关的项目?
  6. TCP和UDP的区别?(有没有握手过程)
  7. 掌握操作系统?掌握到什么地步了?Windows还是Linux?讲一下你对操作系统的理解?
  8. 进程和线程的区别?
  9. 反问:您所在部门?工作内容?实习生进来之后需要完成的工作?

{一面二面隔15分钟}
二面:

  1. 自我介绍
  2. 上来就说是校友,机械学院毕业的,很亲切的问了专业是干嘛的,现在研究生好不好毕业,说他们之前毕业比较难
  3. 多人协作的项目中,自己最大收获以及难忘的点。
  4. TCP三次握手的过程?SYN和ACK为什么取这个名字?(这个题答得很不错)
  5. 红眼岛问题(自己之前看过,勉强分析出来了,还不错)
  6. 业余爱好有哪些
  7. 怎么看待加班(接受加班,但是更追求balance)
  8. 自己的职业规划?(技术、技术+沟通 or 纯管理)

    4.28微软技术支持工程师三面

    总结:不要说自己需要学习和提高(人家是招你来干活的,要说自己很行,非常行,擅长),主要聊了个人对于岗位的理解,为什么选择这个岗位。 提问20min,反问10min。

  9. 介绍一下自己的专业?还是和本科差不多是吧?

  10. 为什么打算转行?
  11. 你对技术支持工程师的理解?
  12. 会不会觉得很枯燥?什么样的工作让你感兴趣?
  13. 我给你讲一下,你再理解一下?
  14. 如果工作反复失败,你会怎么办?会不会沮丧,怎么解决?
  15. 反问环节。 工作内容?工作的服务对象?现场还是远程?

4.27美团IOS一面

总结:基础知识薄弱(数据库,底层知识),项目经历也需要加强。

  1. 自我介绍。 -> 我看你这边项目都是比较简单的项目,问一些基础知识吧。
  2. 为什么要转行?

    希望能更快的实践。

  3. 你对IOS开发,安卓开发,客户端开发的理解?

  4. STL源码:vector的底层实现?
  5. C++内存模型,线程共享哪些部分?
  6. malloc和new有什么区别?
  7. 虚函数;智能指针;虚函数怎么实现的。
  8. IO模型?比如阻塞IO,非阻塞IO;

阻塞IO模型,非阻塞IO模型,多路IO复用模型,异步IO模型。
解释:前三者都是同步IO,会阻塞进程。
阻塞IO,当数据未准备好时,进程会阻塞;
非阻塞IO,需要不断地查询数据,循环调用,不断查询(类似检查操作是否完成);
多路IO复用(事件驱动IO),轮询查询,select,两次系统调用,优势:可以处理多个连接;
异步IO模型,立即返回,数据准备好之后,通知。

  1. 进程调度算法,进程五状态;
  2. 虚拟内存的作用和实现?扩展实际的物理内存,分段分页,然后转移到硬盘中。
  3. 进程通信方式;
  4. poll、select、epoll的区别?
  5. 输入url之后发生的事情。

    DNS解析->TCP建立连接->发送HTTP请求->服务器处理请求,返回响应结果->关闭TCP连接->浏览器解析网页文件(HTML、CSS、JS)->渲染布局,展示

  6. HTTP报文格式?断点续传在HTTP协议如何实现?头部格式?

  7. 假如让你在应用层设计断点续传,怎么设计?
  8. TCP的拥塞控制原理,如何控制流量大小?
  9. 乐观锁悲观锁,事务的隔离级别;
  10. 协程?
  11. 对B树的理解?B+树?(偷懒没看,真的要被自己懒死了)
  12. 手撕代码: 根据前序遍历和中序遍历还原一棵树(自己定义数据结构,还原树){自己改完之后有6个bug}
  13. 可以实习的时间? ```cpp

    include

    include

    using namespace std; struct treeNode { char val; //bug0 数据类型 treeNode left; treeNode right; treeNode(int v) : val(v), left(NULL), right(NULL) {} };// bug1 分号

treeNode build_tree(string& preOrder, string& inOrder, int prel, int prer, int inl, int inr) { if (prel > prer || inl > inr) return nullptr; treeNode root = new treeNode(preOrder[prel]); //bug2 以prel为索引 int root_val = preOrder[prel]; int pos = find(inOrder.begin(), inOrder.end(), root_val) - inOrder.begin(); //bug3 返回iterator int left_size = pos - inl; //bug4 left_size不能加1,去掉根节点 root->left = build_tree(preOrder, inOrder, prel + 1, prel + left_size, inl, pos - 1); //bug5 prel + 1 + left_size - 1 在第一个节点的基础上,加size-1,表示有size个元素 root->right = build_tree(preOrder, inOrder, prel + 1 + left_size, prer, pos + 1, inr); return root; }

int main() { //int a; //cin >> a; /* 1 2 3 4 5

  1. */
  2. string preOrder = "12453";
  3. string inOrder = "42513";
  4. treeNode* root = build_tree(preOrder, inOrder, 0, preOrder.length() - 1, 0, inOrder.length() - 1);
  5. cout << "Hello World!" << endl;

}

  1. <a name="M0CDx"></a>
  2. # 4.30美团IOS二面(1H)
  3. 总结:目前国内的IOS主要用的是OC,Swift国外用的比较多,轻量级的;IOS是前端;基础知识还不错,自学的效果还可以,开发一个实际有用的项目;问的抽象问题,高层设计比较多。
  4. 1. 输入一个url后发生的过程;
  5. 1. 浏览器是怎么解析HTML网页的? 达到了css和dom树,不太对。
  6. 1. 不同位置的static关键字有什么用?
  7. 1. 程序编译的过程,编译器具体做了哪些事?
  8. 1. 怎么理解泛型?
  9. 1. 设计模式的理解?
  10. 1. 软件工程的理解?比如API端口?
  11. 1. 项目具体的实现难点,业务逻辑?
  12. 1. 还有什么你在项目中的比较有成就的事嘛?
  13. ```cpp
  14. //拓扑排序
  15. #include <iostream>
  16. using namespace std;
  17. int matrix[2[2] = {0};
  18. bool complete_course(vector<vector<int>>& course, int n){
  19. vector<int> indegree(n);
  20. vector<int> outdegree(n);
  21. vector<int> visited(n);
  22. //for(int)
  23. for(auto c : course){
  24. int first = c[0], second = c[1];
  25. outdegree[first]++;
  26. indegree[second]++;
  27. matrix[first][second] = 1;
  28. }
  29. for(int i = 0; i < n; i++){
  30. queue<int> q;
  31. if(indegree[i] == 0){
  32. q.push(i);
  33. }
  34. }
  35. while(!q.empty()){
  36. int front = q.front();
  37. visited[front] = 1;
  38. for(int i = 0; i < n; i++){
  39. if(matirx[front][i] == 1){
  40. indegree[i]--;
  41. }
  42. }
  43. for(int i = 0; i < n; i++){
  44. if(indegree[i] == 0 && visited[i] == 0){
  45. q.push(i);
  46. }
  47. }
  48. }
  49. for(int i = 0; i < n; i++){
  50. if(visited[i] == 0) return false;
  51. }
  52. return true;
  53. }
  54. int main() {
  55. int n = 2;
  56. vector<vector<int>> course[[1,0],[0,1]];
  57. complete_course(course, 2);
  58. cout << "Hello World!" << endl;
  59. }

5.7美团IOS三面

总结:

  • 自己对于业务上的考虑权衡能力实在是太差了,只想着学习自己没用过的技术,而不是业务上的实现。
  • 模型的选择,技术的选择要好好考虑,多问为什么。
  • 最后一面了,问到的具体细节不多,主要是技术选型,实现困难,业务场景。但是也是压力最大一面,需要有很多考虑。
  • 大众点评终端业务部门,小团队按照业务内容划分,用户内容,出行,用户产品。
  • 读写分离,用数据库做持久化
  • 团队内部的容器:Picasso
  1. 自我介绍
  2. 聊天室的项目,实现的功能?
  3. 为什么选择epoll?高并发?
  4. 为什么选择这个技术?想要解决什么业务问题?技术场景?
  5. 为什么采用多进程的方式?
  6. 科普一下你的专业?

    5.17阿里二面

  7. 自我介绍?

  8. 介绍下项目中遇到的最大困难?怎么解决的?
  9. 还有嘛?(再讲一下)
  10. MySQL乐观锁和悲观锁? 乐观锁的版本号是怎么实现的?多个进程同时访问?
  11. 开放性问题:超市排队系统和银行排队系统的不同?
  12. TCP四次挥手
  13. 反问?(不需要金融知识;入门,做一个支付宝DEMO;全局版本号)

    5.17晚阿里突击笔试

    考虑输入要负数、正数和零 面试中的手撕代码:命名规范更重要,加强代码的可读性 数字和字符串的区别,分析清楚,不能混为一谈

  1. #include<string>
  2. #include<iostream>
  3. using namespace std;
  4. //评测题目: 无
  5. //"判断数字是否是回文对称数字
  6. //例如: 12321,13577531 左右对称的数字为回文数字
  7. //01234 01234567
  8. bool ishuiwen(int n) {
  9. //1 2 3 4 return true
  10. //-1 ... -999 return false
  11. if (n < 0) return false;
  12. string num = to_string(n);
  13. int length = num.length();
  14. //if(length == 0) return false;
  15. if (length == 1) return true;
  16. if (length % 2 == 0) {//如果有偶数位
  17. int i = length / 2;
  18. int j = i - 1;
  19. while (i < length && j >= 0) {
  20. if (num[i] != num[j]) return false;
  21. i++; j--;
  22. }
  23. return true;
  24. }
  25. else {//如果奇数位
  26. int i = length / 2 + 1;
  27. int j = length / 2 - 1;
  28. while (i < length && j >= 0) {
  29. if (num[i] != num[j]) return false;
  30. i++; j--;
  31. }
  32. return true;
  33. }
  34. }
  35. int main() {
  36. if (ishuiwen(656)) cout << "YES!";
  37. else cout << "NO!";
  38. }

5.21广联达面试(挂了)

总体面试比较简单,感觉主要考察综合能力,问项目,问一些基础知识

  1. 两个进程间的通信是怎么调试的?
  2. 100个数怎么排序?10000个呢?1亿个数呢?
  3. class和struct的区别
  4. 对设计模式的理解?
  5. 最近在看什么技术的书籍嘛?
  6. 有没有用C++调用过SQL数据库?

    6.3百度一面

  • 商业架构部门,主要做线上检索,模型预估,产品。
  • 技术栈RPC
  • 实习生培养采用导师制

主要问项目和语言,然后两道编程题。 总体来说比较简单。

  • 线程多访问问题怎么解决?不用锁?

    6.4百度二面

  • 问的非常全,项目、操作系统、网络、C++、数据结构和算法,全都问到了。

  • 主要工作内容为挣钱,工程上,采用分布式架构和网络交互,高用户量的场景;业务上,比如MySQL,用户量大就比较吃力。
  • 项目问到我自闭了,知识考察很简单。
  1. 在线直播系统怎么设计架构?
  2. 了解不了解NoSQL数据库?
  3. 选择长连接还是短连接?
  4. 主从模式,假如主服务器挂了,怎么办?