阿里云一面
1.自我介绍
- 感觉说的不够流利,需要重新捋一遍。重新设计一下
2.主要想知道实习做了什么工作?对什么感兴趣?
- 我说的研究方向和数据库相关
3.问我使用数据库的什么?研发or使用?
- 我说区块链与数据库相关高,会接触到使用,分布式数据库使用
4.websocket/rpc长连接,最关键的特点?需要解决的问题是什么?
- 我不太知道,说的确保长连接联通的方式。
- 然后介绍了一下压测项目
5.问TCP三次握手
- 感觉口语化太多,答的还行
- 下次记得说第三次握手的作用
6.TCP四次挥手过程
7.客户端异常关闭连接会发生什么?服务器如何处理?
- 异常关闭,会发送服务端RST消息。在select、或者epoll调用在应用层读取到RST消息,从而关闭连接
- 如果拔掉网线等异常,服务端会发送心跳heart-beat信息给服务端
- 发送心跳几次会关闭?这个地方说错了,说到了重传(这个是消息没收到的时候超时重传)
8.实际操作如何看连接是否出现异常?
- 我说tcpdump进行抓包,看RST来判断是否丢包。
- 对方说要用netstat查看,我说还可以用ping、telnet等来判断
9.问到中间件,讲讲什么业务?我做了些什么?
- 这个部分不清楚,只说到了在主从延迟超过某个限制的时候,从库会开启自动同步。
- 然后对方提到了binlog,我完全不记得,然后就过去了,感觉是个致命的问题
10.一主一备、一主两备?用的什么进行同步的?
- 说采用的一主多备,主库用于写,从库用于读
- 同步不知道,后续说用的binlog
11.问我在最近实习的代码贡献
- 我说通过图形化界面观察延迟
- 然后对方认为我就在人肉观察、手动观察延迟。。。工作没有意义?
12.提到内部用的是不是mysql?问如何同步的?
13.内部的binlog格式是什么样的?
- 我说到binlog的三种形式,statement、row、mixed
- 展开讲了下,然后讲了每种存储的格式
- 表示内部应该用的也是这种mixed格式
14.分库分表?分库分表的目的?什么时候分库分表?分库分表会引入什么问题?
- 分库:解决单库性能瓶颈、不能支持高并发请求
- 分表:单个表数据太大、索引空间占用太大
- 分库缺陷:跨表join(这个我忘了,面试官提醒的)、业务逻辑拆分
15.中间件解决什么问题?面向server端的分布式数据库能解决什么?中间件能不能解决跨库的查询?
- 中间件用来进行跨库join、返回合并
- 面试官说中间件是一个client,与数据无关,没有办法做到跨库join,中间件目的是分库分表的路由。要求用户知道分库分表逻辑,join的在同个库
16.讲到raft算法的脑裂。什么是脑裂,什么时候会发生脑裂,raft是如何解决的脑裂?
- 回答了脑裂是在网络分区的时候,少数派节点之间达成共识的现象。
- 说会在网络恢复没有划分的时候,多数派占据上风,回滚之前信息
脑裂如何解决的这个不知道。
- 实际上脑裂是网络发生分区时,出现多个leader现象 - 网络恢复的时候,集群不再多个分区,leader会比较自己当前的term,小于新leader的话就自动称为follower;分区的所有节点会回滚日志匹配新leader的日志
算法题
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
vector<int> getUnion(vector<int> &nums1, vector<int> &nums2) {
map<int, int> m1, m2;
for (int i = 0; i < nums1.size(); i++) {
m1[nums1[i]]++;
}
for (int i = 0; i < nums2.size(); i++) {
m2[nums2[i]]++;
}
vector<int> res;
auto it = m1.begin();
while(it != m1.end()) {
if (m2.find(it->first) != m2.end()) {
int cnt = min(it->second, m2.find(it->first)->second);
for (int i = 0; i < cnt; i++) {
res.push_back(it->first);
}
}
it++;
}
return res;
}
阿里云二面
- proxy的项目背景是什么,你承担了什么工作?
- 实现了一个可用的反向代理 web 服务器,作为一个个人的网络编程项目
比如了解了整个软件开发的流程
- 确定需求、选定服务器类型、定义数据结构、开发辅助工具、单元测试、核心部分开发、集成测试、性能测试等
- 用c++进行开发,更能深入了解智能指针、typedef、指针、引用、多线程、多进程等内容
- 对网络IO模型、并发、TCP等了解更深入
- 在上一份实习,你主要做了什么, 代码贡献是什么?
- healthy check
- 微服务平台中,你承担了什么工作?你说接口复杂,复杂在哪里?
- 承担的架构设计和接口的开发工作
- 我负责的是网关集群的相关接口,大概在20个接口吧。用户先创建集群,才可以在创建服务的时候选择集群。这个过程会涉及到分组集群绑定、用户信息和团队信息的验证等,逻辑会有点绕。
ps:面完三面,然后在笔试环节挂掉了。。。应该是面评不够好的原因。被淘宝捞了,等了很久
淘宝一面
问题
小米的Gaea主要是做什么的?
- 提到了一些分库分表,读写分离之类的 - 包括数据库连接池这些
Gaea怎么实现库表的发送join的?比如查询库A的表a,b,查询库B的表c,d,将数据结果返回,你连接池怎么定位到对应的库和表?join是如何完成的?
- 有一个namespace的概念,通过namespace找到对应数据库,通过namespace内部有多个分片,每个分片可以认为是一个或者多个库 - 数据库连接池分配对应的mysql实例连接,namespace路由到对应数据库 - 介绍了一下gaea的架构。proxy、cc、web界面这些
TCP为什么三次握手?第三次握手客户端如何判断服务端收没收到?
- 讲了三次握手的原理,两次没办法保证互相得到确认 - 客户端在收到服务端回复的时候其实就默认已经建立链接了,但是需要给服务端回复。此时开始发送数据,没收到回复就超时重传。三次超时断开
拥塞控制是什么,如何实现的?
- 拥塞控制为了减少注入整个网络中的数据包数,减少网络的拥塞程度提出来的 - 通过设置一个拥塞窗口rwnd,接受窗口是rwnd和cwnd的最小值。通过满开始、拥塞避免、快重传和快恢复保证了数据包的注入速度
讲一下虚拟内存,怎么实现的,有什么作用?
- 虚拟内存其实就是存放在磁盘上,字节组织的磁盘快。每个字节对应一块虚拟内存的索引
算法
- 反转链表
- 层序遍历
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int _val):val(_val), next(NULL){}
};
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int _val):val(_val), left(NULL), right(NULL){}
};
//1.
ListNode *reverse(ListNode *head) {
if (head == NULL) {
return head;
}
ListNode *pre = NULL;
ListNode *cur = head;
while (cur) {
ListNode *next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
//2.
vector<int> getLevel(TreeNode *root) {
vector<int> res;
if (root == NULL) {
return res;
}
TreeNode *cur = root;
queue<TreeNode *> q;
q.push(cur);
while (!q.empty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
TreeNode *tmp = q.front();
q.pop();
res.push_back(tmp->val);
if (tmp->left) {
q.push(tmp->left);
}
if (tmp->right) {
q.push(tmp->right);
}
}
}
return res;
}