当前位置: 首页 > 科技观察

字节国际支付十问原创捡蜗牛的小男孩捡蜗牛的小男孩

时间:2023-03-16 10:34:58 科技观察

前言大家好,我是蜗牛。之前有读者去字节面试,面试的是国际支付部。他从记忆中回忆起一些真实的面试题。所以,整理了一个比较完整的答案,希望能帮助大家找工作,加油~1。谈谈你在工作中如何设计数据库表的命名规范,选择合适的字段类型,主键设计,选择合适的字段长度优先考虑逻辑删除而不是物理删除每个表必须的几个字段(如create_time和update_time等)。一张表的字段不宜过多。尽量使用notnull来定义字段。设计表时,评估哪些字段需要建立索引无需严格遵守3NF,通过冗余业务字段减少表关联。避免使用MySQL保留字,不搞外键关联。一般在代码维护中一般会选择INNODB存储引擎来选择合适的统一字符集。如果你的数据库字段是枚举类型,需要在注释中注明时间类型选对了。不推荐使用Storedprocedure(包括存储过程和触发器)。1:N关系设计大字段如何设计考虑是否需要合理设计分库分表索引2、三种范式是什么?你做过违反三范式的设计吗?第一种范式:对于属性的原子性,要求属性是原子的,不能分解;第二种范式:对于记录的唯一性,要求记录具有唯一标识,即实体的唯一性,即不存在部分依赖;第三种方法:字段冗余要求任何字段不能从其他字段派生,要求字段之间没有冗余,即没有传递依赖。我们在设计表与字段的关系时,尽量满足第三范式。但有时,可以通过适当的冗余来提高效率。3、四波TCP?你能挥三下吗?第一次挥手(FIN=1,seq=u),发送后,客户端进入FIN_WAIT_1状态,第二次挥手(ACK=1,ack=u+1,seq=v),发送完成后,服务器进入CLOSE_WAIT状态。客户端收到确认包后,进入FIN_WAIT_2状态,第三次挥手(FIN=1,ACK=1,seq=w,ack=u+1),发送后,服务端进入LAST_ACK状态,等待来自客户端的最后一个ACK??。第四次挥手(ACK=1,seq=u+1,ack=w+1),客户端收到服务端的关闭请求,发送确认包,进入TIME_WAIT状态,等待固定时间(两个MaximumSegmentLifetimes,2MSL,2MaximumSegmentLifetime),没有收到服务器的ACK,认为服务器正常关闭了连接,于是自己关闭了连接,进入了CLOSED状态。服务器收到确认包后,关闭连接,进入CLOSED状态。为什么TCP需要四次挥手?可以做三遍吗?举个生活中的例子,假设小明和小红正在打电话,电话快结束的时候:小红说:“我没什么好说的。”小明回答:“我知道。”但是小明可能还有话要说,小红不能让小明按照自己的节奏结束通话,所以小明可能又唠叨了一遍,最后小明说“我说完了”,小红回复“知道了”,通话到此结束。4.进程线程的区别,打开迅雷是一个进程。进程是正在运行的应用程序,线程是进程内部的执行顺序,进程是资源分配的最小单位,线程是CPU调度的最小单位。一个进程可以有多个线程。线程也称为轻量级进程。多个线程共享一个进程的资源。进程之间的切换成本很高。线程之间的切换成本很小。进程拥有更多资源,线程拥有更少资源。地址进程有地址空间,但线程本身没有地址空间。线程的地址空间包含在进程中。比如:当你打开QQ时,就打开了一个进程;打开迅雷的同时,也打开了一个进程。在QQ的这个过程中,开了一个线程发送文字,一个线程发送语音,还有一个线程弹出对话框。所以运行某个软件就相当于开启了一个进程。在本软件运行过程中(本进程中),支持多个作业来完成对QQ的操作,所以这些“多个作业”中的每一个都有一个线程。所以一个进程管理多个线程。通俗地说:“进程是父亲和母亲,掌管着很多线程儿子”……5、进程之间如何通信?进程间有几种通信方式:管道消息队列共享内存信号量信号每个进程的用户地址空间相互独立,不能互相访问。内核空间是每个进程共享的,所以进程之间的通信必须通过内核。管道:其实质是内核中的一串缓存。它在一个方向上传输数据。这种通信方式效率低下,不适合进程间频繁的数据交换。比如我们写linux命令时,ps-ef|grepjava中的“|”垂直线是匿名管道。消息队列:它是存储在内核中的消息链表。消息的发送者和接收者应该就消息体的数据类型达成一致。有了消息队列,两个进程之间的通信就像发邮件一样,你给我发一封。但是它也有缺点,沟通不及时,二是附件也有大小限制。共享内存:就是取出一个虚拟地址空间,映射到同一个物理内存,省去用户态和内核态切换的开销。信号量:其实是一个整型计数器,主要用来实现进程间的互斥和同步,而不是为了进程间通信缓存数据。为了防止多个进程竞争共享资源造成的数据混乱。信号:是进程间通信机制中唯一的异步通信机制,因为它可以随时向某个进程发送信号。Socket:如果要通过网络与不同主机上的进程进行通信,就需要一个socket。6.什么是零拷贝?有多少种方式可以实现零拷贝?哪些中间件应用了零拷贝技术?零拷贝是指计算机在进行IO操作时,CPU不需要将数据从一个存储区拷贝到另一个存储区,从而减少上下文切换和CPU拷贝时间。它是一种I/O操作优化技术。实现零拷贝主要有3种方式:mmap+writesendfilesendfile带DMA集合拷贝功能的Kafka。为什么卡夫卡这么快?它还与零拷贝技术有关。之前写过一篇关于零拷贝技术的文章,得到了很多读者的好评。可以看看,看完就明白了:零拷贝详解7.分布式锁是怎么设计的?有哪些陷阱?8.Redis跳表跳表是有序集合zset的底层实现之一跳表支持平均O(logN)和最差O(N)复杂度的节点查找,也可以通过顺序操作批量处理节点。跳表实现由两个结构组成,zskiplist和zskiplistNode,其中zskiplist用于保存跳表信息(如头节点、尾节点、长度),zskiplistNode用于表示跳表节点。跳表是在链表的基础上,加入多级索引,提高查找效率。9、你平时是如何优化慢SQL数据库的慢查询的?主要有这几个原因。如果SQL没有索引,则添加适当的索引。最左匹配原则等)注意限制深度分页的问题(标签记录法和延迟关联法)单表数据量过大(再分库分表)join或子??查询过多(尽量不要超过3个表Connection,关联的字段需要加索引)in元素过多(in元素查询个数有限制)数据库在清理脏页按文件排序order拿不到锁delete+insubquery不使用索引!详细解释可以看我之前的文章:盘点MySQL查询慢的12个原因10.从十亿个数中找出最小的10个。这是一个经典的TopK问题。可以用分治法+快速排序原理解决。直接上代码classSolution{publicint[]getLeastNumbers(int[]arr,intk){if(arr==null||arr.length==0){returnnull;}//k大于arr数组,直接返回arrif(k>=arr.length)returnarr;intlow=0,high=arr.length-1;快(arr,低,高,k);//返回前K个最大的元素返回Arrays。副本(arr,k);}voidquick(int[]arr,intlow,inthigh,intk){if(lowk-1){quick(arr,low,pivot-1,k);}else{//如果pivot<=k-1,low指针需要向右移动,所以low=pivot+1quick(arr,pivot+1,high,k);}}}privateintpartition(int[]arr,intlow,inthigh){//取arr[low]作为主元pivotintpivot=arr[低];while(low=pivot){high--;}//交换arr[low]=arr[high];//找到左边比pivot大的那个while(low