文章目录
微信、字节和shopee已拿意向书。
字节跳动提前批 - 后端开发 - 技术中台方向
字节提前批一面
先来个个人介绍
实习经历
介绍实习经历;
Svrkit(rpc 框架)的原理;
Protocol buffer 相对于 json 的优点;
计网
http 1.0、1.1、2.0 的区别
三次握手、四次挥手;
accept() 等待的时候,底层的原理是啥?有哪些结构?
会有三次挥手的情况吗?
服务端和客户端同时调用 close() 会怎么样;
数据库
Innodb 中的索引用了什么数据结构?B+树
什么情况会用到哈希索引?会存到硬盘吗?
Redis
(个人项目中用到了 Resis、kafka、Elasticsearch 等)
Redis 的 zset 底层是啥?跳表;
讲一讲跳表;
zset 还用到了哈希表,用来干啥?
Redis 持久化的方式 - rdb 和 aof;
rdb 结束或者 aof 重写结束的时候,子进程如何通知父进程;
Kafka
原理;
发送消息的三种方式;
reblance 原理(消费者组中的数量变化时);
操作系统
linux 的虚拟内存的布局(堆、栈、内存低地址到高地址存的是什么);
进程栈和线程栈的区别?
算法题
判断单链表有没有环,有的话找出入环节点
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
}
}
我写的:
import java.util.Scanner;
public class Main {
public ListNode detechCycle(ListNode head) {
if (head == null && head.next == null) {
return null;
}
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null && slow != fast) {
slow = slow.next;
fast = fast.next.next;
}
if (slow == fast) {
fast = head;
while (slow != fast) {
fast = fast.next;
slow = slow.next;
}
return slow;
} else {
return null;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt();
System.out.println(a);
System.out.println("Hello World!");
}
}
字节提前批二面
Java
volatile 和 synchronized 关键字 - 功能和区别;
ReentrantLock 和 Condition 的用法;
signal() 和 signalAll() 用哪个比较好;
Linux
怎么看内存情况:free -h ;(刚好面试前看到了,你说巧不巧)
free -h 显示的 buffer 和 cache 有什么区别?(超出知识范围,瞎扯了一下 CPU 和内存间的高速缓存,内存和磁盘间的写缓存,还有redo log buffer,能水就水)
计网
DNS 访问流程:本地DNS服务器 - 根DNS服务器 - 顶级域DNS服务器 - 权威DNS服务器;
DNS 用的传输层协议:UDP;
DNS 劫持,怎么防御:答了HTTPS;
HTTPS 流程:证书 - 验证 - 用对称加密来通信
数据库
事务的四个隔离级别;
有了可重复读,为什么还需要串行化:防止幻读;
有了解 MVCC 吗:不了解。告辞;
个人项目
怎样提高网站的性能:ThymeLeaf 模板引擎的缓存;借助 Kafka 来异步处理事件;用 Redis 做缓存和存储存活期短的信息(如验证码);用 Elasticsearch 做全文搜索(不会吧不会吧,不会还有人用 MySQL 的全文索引吧,手动狗头.jpg);利用线程池的方式,一个线程处理一个请求,同时通过 ThreadLocal 给每个线程绑定当前请求对应的用户信息,比如通过拦截器的方式,请求到达时,检查cookie信息,然后。。。;
加入帖子很多,用户数量多,怎么搞:(面试官应该是想我答分库分表,但是我没答出来)
数据结构
建堆(heap)的复杂度:如果已经有全部数据,那就从下到上建堆,O(N);如果是数据流,只能从上到下建堆,O(N*logN)
算法题
给定m * n矩阵matrix,可以从任意位置开始,向上、向下、向左、向右移动,但要求下一个位置上的元素要大于当前元素,找出矩阵中最长的递增路径的长度。
我写的:
import java.util.Scanner;
public class Main {
public static int findLength(int[][] matrix, int[][] length, int i, int j) {
if (length[i][j] != 0) {
return length[i][j];
}
int result = 1;
if (i - 1 >= 0 && matrix[i - 1][j] > matrix[i][j]) {
result = Math.max(result, findLength(matrix, length, i - 1, j) + 1);
}
if (i + 1 < matrix.length && matrix[i + 1][j] > matrix[i][j]) {
result = Math.max(result, findLength(matrix, length, i + 1, j) + 1);
}
if (j - 1 >= 0 && matrix[i][j - 1] > matrix[i][j]) {
result = Math.max(result, findLength(matrix, length, i, j - 1) + 1);
}
if (j + 1 < matrix[0].length && matrix[i][j + 1] > matrix[i][j]) {
result = Math.max(result, findLength(matrix, length, i, j + 1) + 1);
}
length[i][j] = result;
return result;
}
public static int longestPath(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0] == null) {
return 0;
}
int rowSize = matrix.length;
int colSize = matrix[0].length;
int[][] length = new int[rowSize][colSize];
int result = 0;
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
result = Math.max(result, findLength(matrix, length, i, j));
}
}
return result;
}
public static void main(String[] args) {
//Scanner in = new Scanner(System.in);
//int a = in.nextInt();
//System.out.println(a);
System.out.println("Hello World!");
}
}
字节提前批三面
之前面试中不熟悉的知识点,有没有去康康:有;
来讲讲:讲了MVCC,undo log,两段锁协议等等;
一面中http 1.0/1.1/2.0答得没有很好,回去有看吗:看了,(可看我的总结:https://blog.csdn.net/alexkx/article/details/107582427 )
TCP连接中,影响带宽的因素有哪些?(我答了发送到缓存的速度,对方读缓存的速度,拥塞控制等等)
编程语言,数据库,计网,操作系统,哪个最熟:瑟瑟发抖;
(中间有的问题忘了)
写个 sql 吧:
给定一个表 T(id, name, age, sex, city),写出一下查询语句:男性平均年龄最高的城市。
select city
from (select avg(age) as A, city
from T
where sex = "male"
group by city) as Temp
where A >= (select Temp.A from Temp);
select city
from (select avg(age) as A, city
from T
where sex = "male"
group by city) as Temp
order by A desc
limit 0,1;
做个概率题
一种流行病患病概率是1%,有一种检测试纸,检测的准确率是99%,我现在试纸检测阳性了,请问我患病的概率有多大? (概率论有点忘了)
再来做两题:
用一个[0,4)的随机数生成器rand4(),模拟一个[0.6)的随机数rand6() - 常见题,直接口述
32个石块,重量不等,用天平来进行衡量,找出最重的石块,最少需要几次? - 考官提示了一下,用归并的方法,应该是31次
如果是找出最重的两块,需要几次?我答了46次,看网上有的人说31次,感觉不是很对。
shopee 后端开发
笔试(2020.7.29)
10题计算机相关的选择题
5题数学相关的选择题
3题编程题:
- 用多重背包算法来做
- 根据给出的数据建二叉搜索树,在返回所有叶子节点
- k个一组翻转链表 - leetcode25
(AC了2.8题)
一面
进程间的通信方式:管道(匿名和命名)、消息队列、共享内存&信号量、信号;ipcs 查看 ipc 对象;
内核空间和用户空间;为啥要这么区分;
分段机制、分页机制;
TCP四次挥手;
TCP 流量控制和拥塞控制;
输入 https://www.shopee.com 以后的过程:DNS查询、TCP 三次握手、验证证书、生成对称加密的秘钥,如果是 http/2.0,服务器还会主动推送相关资源。
websocket 有了解吗:没有;
IO 多路复用的几种系统调用(select、poll、epoll),主要区别;
介绍一下红黑树;
介绍一下 B+树、B树;
Java 多线程实现方式(就是怎么用多线程执行任务,比如实现 Runnable接口,实现 Callable 接口,继承 Thread 类);
MySQL的持久化手段,比如执行update 语句时,如何保证数据持久化:答了redo log,binlog,undo log等等;
ACID 是啥;
Redis 的 sorted set 底层的数据结构(跳表),原理;
Kafka 原理,怎么保证高可用、高性能:分区、主从备份、顺序IO、每个消息只在分区主节点保存一份等等;
最后是一题简单题:
在字符串中找出连续最长的数字串
样例输出
输出123058789,函数返回值9
输出54761,函数返回值5
接口说明
函数原型:
unsignedint Continumax(char** pOutputstr, char* intputstr)
输入参数:
char* intputstr 输入字符串;
输出参数:
char** pOutputstr: 连续最长的数字串,如果连续最长的数字串的长度为0,应该返回空字符串;如果输入字符串是空,也应该返回空字符串;
返回值:
连续最长的数字串的长度
输入描述
输入一个字符串。
输出描述
输出字符串中最长的数字字符串和它的长度。如果有相同长度的串,则要一块儿输出,但是长度还是一串的长度
示例1
输入
abcd12345ed125ss123058789
输出
123058789,9
import java.util.Scanner;
public class Main {
public static int read(char[] arr, int begin) {
int cur = begin;
while (cur < arr.length) {
if (arr[cur] <= '9' && arr[cur] >= '0'){
cur++;
} else {
break;
}
}
return cur;
}
public static void Continumax(String input) {
if (input == null || input.length() == 0) {
System.out.println(", 0");
}
char[] arr = input.toCharArray();
int resultBegin = -1;
int resultSize = 0;
int i = 0;
while (i < arr.length) {
if (arr[i] <= '9' && arr[i] >= '0'){
int end = read(arr, i);
if (end - i > resultSize) {
resultSize = end - i;
resultBegin = i;
}
i = end;
} else {
i++;
}
}
if(resultSize > 0) {
System.out.printf("%s, %d", input.substring(resultBegin, resultBegin + resultSize), resultSize);
} else {
System.out.println(", 0");
}
}
public static void main(String[] args) {
//Scanner in = new Scanner(System.in);
//int a = in.nextInt();
//System.out.println(a);
String input = "abcd12345ed125ss123058789";