阿里3.26Java研发工程师一面面经
需要注意的点:
- 不要说废话
- 不要给自己挖坑,不会的点不要说
- 不要说太多,点到为止,让面试官提问
- 上来先自我介绍
- 问项目和基础的知识点
- 问对哪方面感兴趣,有没有读技术博客的习惯
- 场景题,如何保证聊天信息的发送不会重复,确认送达
- 自己做过的时间最长的一件事?在这其中遇到的最大的困难?如何解决的
- 讲一下二叉排序树、平衡二叉树
- 讲一下C++和Python之间的区别(因为我提到了自己会这两种语言)
- 讲一下对OSI七层网络模型的理解。。。详细讲一下哪几层
- 详细介绍其中一个层,比如物理层?(主要是传输介质?是。。)还能想到别的嘛?
开放性问题
- 对于网络聊天的想法?消息是怎么发送过来的?对异常情况怎么处理(到达、重复)?
- 网络聊天是怎样一个流程?端到端的一个流程?
寻找位置、确认身份、建立连接、发送消息。
- 端到端是可以直接建立连接嘛? 不是,需要经过服务器转发。
- 服务器具体是怎样处理的?解包,转发。
- 会不会存在发送消息丢了,重发的情况,比如客户端收到两条?不会,网络协议会保证可靠性和不重传。主要是通过传输层和应用层来保证。
- 通信怎么判别消息是否重复?序列号机制。 其他还有吗? 想不到了。
- 了不了解网络爬虫? 了解,爬虫是搜索引擎的基础,从一个网页遍历到另一个网页,建立索引库。
- 有没有做过网络爬虫的应用?做过简单的应用,模拟登录豆瓣网、知乎。
- 做的初衷是什么?是有需要还是好奇? 出于好奇。
- 爬到数据之后有没有做别的处理? 没有。
按照实际和日常来聊
- 分享一些开始不是很擅长但是后来居上的例子? 运动,高中不擅长,大学坚持运动
- 你觉得由原来的不擅长到擅长最重要的原因是什么呢?有达到你的预期吗? 时间上的积累,速成很难,不断地练习,反思。
- 你做的最久的一件事?有没有遇到什么困难,怎么克服的?hhh整理的过程中突然想到了吃饭和睡觉。 我回答的学英语,从初中到大学,小有成就。困难,很难坚持下来;方法,不断设定新的目标,考试。
- 有更实际一些的困难吗?实际的困难和解决方法? 闭门造车,不知道自己的进度,算吗? 按照你自己的理解就好啦。。。 多交流,多找参照物,寻找反馈。
- 学习之余的生活会不会看技术资料和技术博客? 看的比较少,学啥看啥。先看工程,再看深度精进。
- 在技术领域方面有没有比较感兴趣的?或者说深入了解过哪方面? 网络,自己对翻墙有需求,所以了解过,从shadowsock到trojan。
- 研究过但是没有开发过? 是的。
- 你觉得难点会在什么地方? 首先确定框架,首先选择协议,然后是实现细节。 主要是地基要打好,否则很容易被封。
- 原理你了解到了多深的程度?仅仅是了解,扫了几眼。
- 能不能分享作为团队的组织者或者领导者的经历? 本科期间的大创。首先拉人,然后分工,在项目进行过程中调整分工,做好利益分配。
- 项目中最复杂的事情,最复杂的任务? 这部分答得太差,答不到重点上。
- 有具体点的例子吗? 确定任务计划书的过程,开会调研。
- 在本科、硕士期间有没有突出的成绩,比如竞赛或者论文?
- 在知名比赛、科技公司、实验室有没有突出的技术贡献?发表过专利?只发表过一篇论文。
- 论文发表在哪里?论文的内容?
- 你有没有什么想了解的?
- 您最近在做什么工作? 支付业务,服务端的整体链路。
- 对我有什么建议?面试按照正常发挥就OK了,你的表现是比较自然的,把最真实的自我表现出来就OK了。不只看技术能力,会看一些综合情况。会看学校的情况,个人的一些特质。
- 如何提高? 不是科班出身,如果真的有兴趣,可以多深挖,研究一下。有兴趣的,多坚持一下。不一定用到再去看,真的有兴趣就多看一点。
3.28腾讯客户端开发面经
开始自我介绍,问项目,然后问基础知识,操作系统,网络,C++这些,最后两道编程题。
冒泡排序的递归写法:
自己开始写的双层for循环的写法,自己开始写的神奇方法把自己和面试官都搞懵逼了,后来发现自己写的代码其实是有问题的,并不是冒泡排序(相邻两个数,比较交换),只是每次保证i位置元素最小,类似选择排序?
#include <iostream>using namespace std;void bubble_sort(int arr[], int n){for(int i = 0; i < n; i++){for(int j = i; j < n; j++){if(arr[i] > arr[j]){swap(arr[i], arr[j]);}}}}int main() {int arr[] = {5, 4, 2, 3, 6};int n = 5;bubble_sort(arr, 5);for(int i = 0; i < n; i++){cout<<arr[i]<<endl;}}
然后在面试官的提示下改成了递归写法,去掉了一个for,一层一层递归,还是类似选择排序的方法。
#include <iostream>using namespace std;void bubble_sort(int arr[], int i, int n){for(int j = i; j < n; j++){if(arr[i] > arr[j]){swap(arr[i], arr[j]);}}if( i < n ) bubble_sort(arr, i + 1, n);}int main() {int arr[] = {5, 4, 2, 3, 6};int n = 5;bubble_sort(arr, 0, 5);for(int i = 0; i < n; i++){cout<<arr[i]<<endl;}}
最后自己查了一下,这个才是真正的冒泡排序啊!比较相邻元素,大元素上冒,然后每次上边界-1
加一个flag判断,假如不需要排序了,直接退出即可
非递归写法
#include <iostream>using namespace std;void bubble_sort(int arr[], int n) {for (int i = n - 1; i >= 0; i--) {//排序的上界,每次减1int flag = 0;for (int j = 0; j < i; j++) {if (arr[j] > arr[j + 1]) {swap(arr[j + 1], arr[j]);flag = 1;}if (!flag) return;}}}int main() {int arr[] = { 5, 4, 2, 3, 6 };int n = 5;bubble_sort(arr, 5);for (int i = 0; i < n; i++) {cout << arr[i] << endl;}}
递归写法, 上界要写成n-1,防止越界
#include <iostream>using namespace std;void bubble_sort(int arr[], int n) {int flag = 0;for (int i = 0; i < n - 1; i++) {if (arr[i] > arr[i + 1]) {swap(arr[i + 1], arr[i]);flag = 1;}}if (!flag) return;if (n > 0) bubble_sort(arr, n - 1);}int main() {int arr[] = { 5, 4, 2, 3, 6 };int n = 5;bubble_sort(arr, 5);for (int i = 0; i < n; i++) {cout << arr[i] << endl;}}
实现双向队列,实现头尾插入或者删除
写队列,自己直接就想到了数组的方法,写完之后面试官就问如果超出容量怎么办;想了一会才想到采用链表的方法,真是太菜了。
然后在写的过程中发现对于类的定义和指针操作这些不熟练,边写边害怕是不是写错了。
#include <iostream>using namespace std;class deque {struct Node {int num;Node* pre;Node* next;Node(int n) :num(n), pre(NULL), next(NULL) {}};struct Node* front;struct Node* back;public:deque(int num) {front = new struct Node(num);back = front;}void front_insert(int num) {struct Node* ptr = new struct Node(num);front->next = ptr;ptr->pre = front;front = front->next;}void back_insert(int num) {struct Node* ptr = new struct Node(num);back->pre = ptr;ptr->next = back;back = back->pre;}void front_delete() {struct Node* tmp = front;front = front->pre;front->next = nullptr;delete tmp;}void back_delete() {struct Node* tmp = back;back = back->next;back->pre = nullptr;delete tmp;}};int main() {deque q(-1);q.front_insert(2);q.back_insert(2);q.front_insert(4);q.back_insert(5);q.front_delete();q.back_delete();return 0;}
4.24微软技术支持工程师
总结:考察的点主要在经历、综合素质以及职业规划,专业知识主要考察TCP协议(之前邮件里提示过要看了)。
一面:
- 自我介绍
- 介绍一个主要的项目
- 在这个项目中遇到的最大困难,怎么克服的?
- 项目中的沟通协调问题?做的好的,做的不好地方?
- 介绍一下CS相关的项目?
- TCP和UDP的区别?(有没有握手过程)
- 掌握操作系统?掌握到什么地步了?Windows还是Linux?讲一下你对操作系统的理解?
- 进程和线程的区别?
- 反问:您所在部门?工作内容?实习生进来之后需要完成的工作?
{一面二面隔15分钟}
二面:
- 自我介绍
- 上来就说是校友,机械学院毕业的,很亲切的问了专业是干嘛的,现在研究生好不好毕业,说他们之前毕业比较难
- 多人协作的项目中,自己最大收获以及难忘的点。
- TCP三次握手的过程?SYN和ACK为什么取这个名字?(这个题答得很不错)
- 红眼岛问题(自己之前看过,勉强分析出来了,还不错)
- 业余爱好有哪些
- 怎么看待加班(接受加班,但是更追求balance)
-
4.28微软技术支持工程师三面
总结:不要说自己需要学习和提高(人家是招你来干活的,要说自己很行,非常行,擅长),主要聊了个人对于岗位的理解,为什么选择这个岗位。 提问20min,反问10min。
介绍一下自己的专业?还是和本科差不多是吧?
- 为什么打算转行?
- 你对技术支持工程师的理解?
- 会不会觉得很枯燥?什么样的工作让你感兴趣?
- 我给你讲一下,你再理解一下?
- 如果工作反复失败,你会怎么办?会不会沮丧,怎么解决?
- 反问环节。 工作内容?工作的服务对象?现场还是远程?
4.27美团IOS一面
总结:基础知识薄弱(数据库,底层知识),项目经历也需要加强。
- 自我介绍。 -> 我看你这边项目都是比较简单的项目,问一些基础知识吧。
为什么要转行?
希望能更快的实践。
你对IOS开发,安卓开发,客户端开发的理解?
- STL源码:vector的底层实现?
- C++内存模型,线程共享哪些部分?
- malloc和new有什么区别?
- 虚函数;智能指针;虚函数怎么实现的。
- IO模型?比如阻塞IO,非阻塞IO;
阻塞IO模型,非阻塞IO模型,多路IO复用模型,异步IO模型。
解释:前三者都是同步IO,会阻塞进程。
阻塞IO,当数据未准备好时,进程会阻塞;
非阻塞IO,需要不断地查询数据,循环调用,不断查询(类似检查操作是否完成);
多路IO复用(事件驱动IO),轮询查询,select,两次系统调用,优势:可以处理多个连接;
异步IO模型,立即返回,数据准备好之后,通知。
- 进程调度算法,进程五状态;
- 虚拟内存的作用和实现?扩展实际的物理内存,分段分页,然后转移到硬盘中。
- 进程通信方式;
- poll、select、epoll的区别?
输入url之后发生的事情。
DNS解析->TCP建立连接->发送HTTP请求->服务器处理请求,返回响应结果->关闭TCP连接->浏览器解析网页文件(HTML、CSS、JS)->渲染布局,展示
HTTP报文格式?断点续传在HTTP协议如何实现?头部格式?
- 假如让你在应用层设计断点续传,怎么设计?
- TCP的拥塞控制原理,如何控制流量大小?
- 乐观锁悲观锁,事务的隔离级别;
- 协程?
- 对B树的理解?B+树?(偷懒没看,真的要被自己懒死了)
- 手撕代码: 根据前序遍历和中序遍历还原一棵树(自己定义数据结构,还原树){自己改完之后有6个bug}
- 可以实习的时间?
```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
*/string preOrder = "12453";string inOrder = "42513";treeNode* root = build_tree(preOrder, inOrder, 0, preOrder.length() - 1, 0, inOrder.length() - 1);cout << "Hello World!" << endl;
}
<a name="M0CDx"></a># 4.30美团IOS二面(1H)总结:目前国内的IOS主要用的是OC,Swift国外用的比较多,轻量级的;IOS是前端;基础知识还不错,自学的效果还可以,开发一个实际有用的项目;问的抽象问题,高层设计比较多。1. 输入一个url后发生的过程;1. 浏览器是怎么解析HTML网页的? 达到了css和dom树,不太对。1. 不同位置的static关键字有什么用?1. 程序编译的过程,编译器具体做了哪些事?1. 怎么理解泛型?1. 设计模式的理解?1. 软件工程的理解?比如API端口?1. 项目具体的实现难点,业务逻辑?1. 还有什么你在项目中的比较有成就的事嘛?```cpp//拓扑排序#include <iostream>using namespace std;int matrix[2[2] = {0};bool complete_course(vector<vector<int>>& course, int n){vector<int> indegree(n);vector<int> outdegree(n);vector<int> visited(n);//for(int)for(auto c : course){int first = c[0], second = c[1];outdegree[first]++;indegree[second]++;matrix[first][second] = 1;}for(int i = 0; i < n; i++){queue<int> q;if(indegree[i] == 0){q.push(i);}}while(!q.empty()){int front = q.front();visited[front] = 1;for(int i = 0; i < n; i++){if(matirx[front][i] == 1){indegree[i]--;}}for(int i = 0; i < n; i++){if(indegree[i] == 0 && visited[i] == 0){q.push(i);}}}for(int i = 0; i < n; i++){if(visited[i] == 0) return false;}return true;}int main() {int n = 2;vector<vector<int>> course[[1,0],[0,1]];complete_course(course, 2);cout << "Hello World!" << endl;}
5.7美团IOS三面
总结:
- 自己对于业务上的考虑权衡能力实在是太差了,只想着学习自己没用过的技术,而不是业务上的实现。
- 模型的选择,技术的选择要好好考虑,多问为什么。
- 最后一面了,问到的具体细节不多,主要是技术选型,实现困难,业务场景。但是也是压力最大一面,需要有很多考虑。
- 大众点评终端业务部门,小团队按照业务内容划分,用户内容,出行,用户产品。
- 读写分离,用数据库做持久化
- 团队内部的容器:Picasso
- 自我介绍
- 聊天室的项目,实现的功能?
- 为什么选择epoll?高并发?
- 为什么选择这个技术?想要解决什么业务问题?技术场景?
- 为什么采用多进程的方式?
-
5.17阿里二面
自我介绍?
- 介绍下项目中遇到的最大困难?怎么解决的?
- 还有嘛?(再讲一下)
- MySQL乐观锁和悲观锁? 乐观锁的版本号是怎么实现的?多个进程同时访问?
- 开放性问题:超市排队系统和银行排队系统的不同?
- TCP四次挥手
- 反问?(不需要金融知识;入门,做一个支付宝DEMO;全局版本号)
5.17晚阿里突击笔试
考虑输入要负数、正数和零 面试中的手撕代码:命名规范更重要,加强代码的可读性 数字和字符串的区别,分析清楚,不能混为一谈
#include<string>#include<iostream>using namespace std;//评测题目: 无//"判断数字是否是回文对称数字//例如: 12321,13577531 左右对称的数字为回文数字//01234 01234567bool ishuiwen(int n) {//1 2 3 4 return true//-1 ... -999 return falseif (n < 0) return false;string num = to_string(n);int length = num.length();//if(length == 0) return false;if (length == 1) return true;if (length % 2 == 0) {//如果有偶数位int i = length / 2;int j = i - 1;while (i < length && j >= 0) {if (num[i] != num[j]) return false;i++; j--;}return true;}else {//如果奇数位int i = length / 2 + 1;int j = length / 2 - 1;while (i < length && j >= 0) {if (num[i] != num[j]) return false;i++; j--;}return true;}}int main() {if (ishuiwen(656)) cout << "YES!";else cout << "NO!";}
5.21广联达面试(挂了)
总体面试比较简单,感觉主要考察综合能力,问项目,问一些基础知识
- 两个进程间的通信是怎么调试的?
- 100个数怎么排序?10000个呢?1亿个数呢?
- class和struct的区别
- 对设计模式的理解?
- 最近在看什么技术的书籍嘛?
- 有没有用C++调用过SQL数据库?
6.3百度一面
- 商业架构部门,主要做线上检索,模型预估,产品。
- 技术栈RPC
- 实习生培养采用导师制
主要问项目和语言,然后两道编程题。 总体来说比较简单。
