字节跳动C++云原生二面(65min)
Posted MangataTS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字节跳动C++云原生二面(65min)相关的知识,希望对你有一定的参考价值。
字节跳动C++云原生二面(65min)
面试问题
HTTP1.0 、1.1和2.0 的区别和差异是什么
- 《HTTP1.0和1.1的区别》
- HTTP1.1 默认开启长连接(
keep-alive
) 而HTTP1.0需要添加参数,在一定程度上减少了建立和关闭连接的消耗和延迟- HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。HTTP1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求body发送到服务器;如果返回401,客户端就可以不用发送请求body了节约了带宽。
- HTTP1.0中认为每台服务器只有一个唯一的IP地址,因此请求头中的URL中并没有传递主机名,因此HTTP1.0没有host域,但是HTTP1.1的请求消息必须有host域(host域其实就是一个记录IP和域名的文件,可以加快解析速度)
- 在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
- 在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
- 《HTTP1.1和2.0的区别》
- HTTP2.0使用多路复用的技术,做到同一个连接并发处理多个请求,并且并发请求的数量也比HTTP1.1大了好几个数量级,要比HTTP1.1多建几个TCP连接的开销更小
- HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
- 支持服务器推送 ,为了改善延迟,HTTP2.0引入了server push,它允许服务端推送资源给浏览器,在 浏览器明确地请求之前 ,免得客户端再次创建连接发送请求到服务器端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络。
- HTTP2.0采用二进制格式传输数据
WebSocket 也是基于Http协议的对吧
WebSocket在建立连接的时候是使用的HTTP协议,建立连接之后就是自己的WebSocket协议了
HTTPS有用到过吗,HTTPS在数据传输的过程中是对称加密还是非对称加密
HTTPS 在内容传输的加密上使用的是对称加密,非对称加密只作用在证书验证阶段
整体过程分为:证书验证 和 数据传输 阶段
证书验证的时候会拿公钥做什么事情
会将公钥去加密由一个权威服务器生成的一个随机数字,然后再发送给服务器端,服务器端通过私钥解密随机数,然后服务器通过客户端传入的随机数进行构造对称加密算法,对返回结果内容进行对称加密后传输给客户端
为什么数据传输是用的对称加密
- 非对称加密的加解密效率是非常低的,而 http 的应用场景中通常端与端之间存在大量的交互,非对称加密的效率是无法接受的
- 在 HTTPS 的场景中只有服务端保存了私钥,一对公私钥只能实现单向的加解密,所以 HTTPS 中内容传输加密采取的是对称加密,而不是非对称加密。
孤儿进程和僵尸进程简单介绍一下
- 僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。(也就是子进程的退出状态不被收集)。
- 父进程如果不等待子进程退出,在子进程之前就结束了自己的“生命”,此时子进程就叫做孤儿进程。
Linux避免系统存在过多孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程。
Pid==1,init进程(初始化进程)
孤儿进程和僵尸线程怎么去避免呢
- 《僵尸进程处理》
- 其实在子进程退出的时候内核会发送SIGCHLD信号给父进程,我们可以捕捉SIGCHLD信号,然后在信号函数中回收子进程,即调用wait
线程之间是怎么同步的,一般有哪些方式
- 信号量:为控制一个具有有限数量用户资源而设计
- 互斥量:为协调共同对一个共享资源的单独访问而设计的
- 读写锁
- 条件变量
- 文件互斥
进程什么时候是在内核态什么时候是在用户态,怎么做一个切换的
从用户态到内核态的转变,需要通过系统调用来完成。比如,当我们查看文件内容时,就需要多次系统调用来完成:首先调用 open() 打开文件,然后调用 read() 读取文件内容,并调用 write() 将内容写到标准输出,最后再调用 close() 关闭文件。
系统调用会将CPU从用户态切换到核心态,以便 CPU 访问受到保护的内核内存。
系统调用的过程会发生 CPU 上下文的切换,CPU 寄存器里原来用户态的指令位置,需要先保存起来。接着,为了执行内核态代码,CPU 寄存器需要更新为内核态指令的新位置。最后才是跳转到内核态运行内核任务。
而系统调用结束后,CPU 寄存器需要恢复原来保存的用户态,然后再切换到用户空间,继续运行进程。所以,一次系统调用的过程,其实是发生了两次 CPU 上下文切换。
注意:系统调用过程中,并不会涉及到虚拟内存等进程用户态的资源,也不会切换进程。
系统调用过程通常称为特权模式切换,而不是进程上下文切换。
死锁你是怎么理解的,什么情况会产生死锁
读写锁这一块你有用过吗,简单介绍一下
平常项目里面也没涉及到读写锁对吧
爬虫这一块,爬数据的时候是并发做爬取的吗,讲一下你的思路,还有你的数据是存储在哪里的?
这个项目是你单独去做的吗?看你投入了一年的时间,当时是出于什么考虑来做这一块呢?你在做的过程中有碰到过比较大的难点吗,比如真正去做一些实现的时候遇到过什么棘手的吗
刚才提到你自学了 python
,你来介绍一下Python中的闭包
你自己比较擅长哪个语言呢
你对云原生感兴趣,那么Golang有尝试去做过一些学习吗
数据库这一块你了解的多吗,比如像mysql,包括像一些关联查询,一些高级的SQL语句什么的,还有索引什么的
比如数据量比较大的情况,比如说你朋友发现我某一个SQL执行的时候比较慢,你觉得如果他执行比较慢的,可能有哪些原因?你怎么去排查定位呢?
索引的回表的操作一般在什么情况发生
volatile这样的关键字的作用是干什么的
你平常和同学做项目的合作过程中你是怎么去写作的,怎么分工的或者是做一个拆解的,谁去做这个事儿
因为你涉及到一些比如参加一些比赛的话,比赛是有人去主导,比如说一些比如参会,你们是主动自己去参加的吗
如果你过来实习的话,比如说给你一个比如说任务或者一个方向,但这一块相对来说又自己比较陌生,你一般会怎么去做?
你有关注哪些云原生的方向或者项目吗?K8s这一块的话有了解过吗?
代码
想了2min,给了一个 N 3 N^3 N3 的思路,先预处理前缀和面积,然后枚举正方形的左上角,以及边长
实现后,面试官问我能不能用动态规划做,当时感觉是可以的,然后想了10min,用 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示 以 ( i , j ) (i,j) (i,j) 点作为正方形的右下角的点的最大正方形的长度 ,发现规律如果左上角三个正方形的面积相等,而面积相等就等价于边长相等就恰巧是我们的 d p dp dp 状态,那么就能合成更大的一个正方形
d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 dp[i][j] = dp[i-1][j-1] + 1 dp[i][j]=dp[i−1][j−1]+1
如果不相等的话,那么就是从三个正方形中选一个最小的加一来合成
d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j − 1 ] , m i n ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) ) + 1 dp[i][j] = min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1])) + 1 dp[i][j]=min(dp[i−1][j−1],min(dp[i−1][j],dp[i][j−1]))+1
当时脑子有点昏,不相等我就直接让他等于 1 1 1 了,面试官说有事,我的思路没问题,细节还需要注意下,然后就run了,现在想来真就差一点
#include<bits/stdc++.h>
using namespace std;
#define N 500
int dp[N][N];
int n,m;
vector<char> matrix[N];
int main()
cin>>n>>m;
for(int i = 0;i < n; ++i)
for(int j = 0;j < m; ++j)
cin>>matrix[i][j];
memset(dp,0,sizeof dp);
int ans = 0;
for(int i = 0;i < n; ++i)
for(int j = 0;j < m; ++j)
if(matrix[i][j] == '1')
if(dp[i][j] == dp[i][j+1] && dp[i][j] == dp[i+1][j] && dp[i][j+1] == dp[i+1][j])
dp[i + 1][j + 1] = dp[i][j] + 1;
else
dp[i + 1][j + 1] = min(dp[i][j],min(dp[i+1][j],dp[i][j+1])) + 1;
ans = max(ans,dp[i+1][j+1]);
pritnf("%d\\n",ans);
return 0;
以上是关于字节跳动C++云原生二面(65min)的主要内容,如果未能解决你的问题,请参考以下文章