2021中大厂php+go面试题(2)
一、前言
废话不多说,本篇是面试题系列的第二篇。文章面试题包括:快手,字节,得物,滴滴,百度等。第一篇面试题为:
2021中大厂php+go面试题(1)
友情提示: 大部分的面试题都是重复的,因此会越写越少。。
二、正文
1、快手一面
1.CDn工作原理答:CDN通过广泛的网络节点分布,提供快速、稳定、安全、可编程的全球内容分发加速服务,支持将网站、音视频、下载等内容分发至接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率。https://blog.csdn.net/aliyunbaike/article/details/84952966
2.go的init用过吗,主要使用场景是哪些?答:每一个源文件都可以包含一个 init 函数,该函数会在 main 函数执行前,
被 Go 运行框架调用,也就是说 init 会在 main 函数前被调用。3.快速排序4.go的map怎么删除元素delete(map, 键)如果要清空map元素,直接make一个新map就可以5.go的syncmap1)map在并发编程中,读是线程安全的,写不是2)sync.map是线程安全的,不需要初始化,声明即可3)Store 表示存储,Load 表示获取,Delete 表示删除4)
2、边锋一面
1.redis的连接跟mysql的连接有什么区别?为什么redis可以承受更高的访问量?io多路复用
2.dns解析的具体流程
3.nginx访问php的方式,优缺点,怎么访问的
4.php获取请求到生成opcode的过程 ,opcode是干什么的,跟机器码有什么区别答:本质上一个opcode由两个参数(op1,op2)、返回值和处理函数组成。它的官方解释就是PHP脚本编译后的中间语言,类似于java中的bytecode或者是.net中的MSL。5.php定义类外的 静态变量,还有类里面的静态变量有什么区别?你说到类里面的静态变量是不会立刻释放的,那么有100个请求去请求这个类,静态变量的值累加,100次之后你认为这个值是多少,为什么
6.php定义类外的 静态变量,还有类里面的静态变量有什么区别?你说到类里面的静态变量是不会立刻释放的,那么有100个请求去请求这个类,静态变量的值累加,100次之后你认为这个值是多少,为什么答:都是在程序一启动时就分配了内存空间,生命周期一样,但是作用域和可见性却不一样1)类内部静态变量必须通过类名或者对象名去访问,该变量在整个程序中都可见。2)类外的静态变量只能在定义文件中使用,只在定义文件中可见,无法在非定义文件中使用。7.nginx发送请求到php,这个请求是什么格式的,里面都包含了哪些内容用户访问域名->域名进行DNS解析->请求到对应IP服务器和端口->nginx监听到对应端口的请求->nginx对url进行location匹配->执行匹配location下的规则->nginx转发请求给php->php-fpm的master进程监听到nginx请求->master进程将请求分配给闲置的worker进程->worker进程执行请求->worker进程返回执行结果给nginx->nginx返回结果给用户nginx连接php的方式:1)tcp方式: ip+9000端口2)unix_socket:(要求nginx和php必须在同一台服务器上)fastcgi_pass unix:/tmp/php-fpm.socket8.redis做队列,如果消费者挂掉了,这个数据丢失怎么办Redis有个命令叫做LPUSHRPOP(以及阻塞版本和不同方向的版本),即从一个队列弹出的同时将这个消息送入另一个队列,同时返回给客户端。原子操作。9.rebbitmq会积压到内存爆掉,kafka为什么不会答:当RabbitMQ收到消息时,如果是持久化消息,则会储存在内存中,同时也会写入磁盘;如果是非持久化消息,则只会存在内存中
3、字节一面
1.bitmap设置的长度是多大,用到了哪些hash函数bitmap底层使用的还是字符串结构,最多是512M,也就是2的32次方 位
2.渐进式hash,对渐进式的理解1)从dict.ht[0].table[0]的bucket进行rehash。2)处理完一个bucket后,将ht[0].table[dict.rehashidx] 置为 NULL。3)将dict.rehashidx加1,处理下一个bucket查询: 比较当前key的大小和 rehashidx的大小,来选择去h0还是h1中进行查询。3.kafka的分区和消费者的分配原则(1)分区数: Tt / max(Tp, Tc)(2) key怎么分配到分区的?1)有key的时候,做一次hash,根据分区数取模2)key为null,则随机找一个分区写入(3)分区和消费者的策略1)range :partitions的个数除于消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区2)将所有主题的分区组成 list列表,然后对 list列表按照 hashCode 进行排序4.统计相同用户的访问次数,sort排序
cat logs/baidu.access.log | awk '{print $(NF-1)}' | sort | uniq -c | sort -k 1 -n -r|head -105.有n个任务,每个任务有开始和结束时间,如何安排任务的顺序,
使得完成的任务个数是最多的
4、b站B部门一面
1.php实现锁1)静态变量(同一个请求的话,会不释放。多个请求的话会初始化)2)apcu 将PHP代码编译之后所产生的bytecode暂存在共享内存内供重复使用,以提升应用的运行效率。(Opcode Cache)提供用户数据缓存功能,需要显示的调用,和redis/memcache类似。(User Data Cache)2.订单表的分库,如何查询?数据量比较大的话呢淘宝的做法是拆分买家库和卖家库,也就是两个库:买家库、卖家库。买家库,按照用户的id来分库分表。卖家库,按照卖家的id来分库分表。写入的时候,先写入买家库,然后通过消息队列异步写入到卖家库。3.http304产生的原因,我们可以用它来实现什么场景4.redis的bitmqp的缺点数据比较松散的情况下不好用
5.go的读写锁6.redis的list做队列,当数据比较多的时候怎么处理?
(1)拆分法
可以遍历list,拆分到多个list中去,多个list可以按照顺序,比如1,-1000,
10001-2000 这样取名字(2)如果有范围查询的需求,可以考虑转换为zset来处理范围查询,按照时间戳
来进行排序即可7.外部请求接口很慢,该怎么排查?服务器资源不足怎么办(1)服务器扩容(2)需要预估一个qps,扩容*120%即可1.内存使用过高,频繁gc导致cpu占满2.内存使用不高,出现了类似死循环场景通过第三方监控平台查看堆栈信息8.lru的加锁,在操作链表的时候需要加读写锁的
5、货拉拉一面
1.php-fpm的超时配置,超时之后会显示什么(1)Nginx 504 Gateway Time-out的含义是没有请求到可以执行的PHP-CGI。(2)Nginx 502 Bad Gateway的含义是请求的PHP-CGI已经执行,但是由于读取资源的程序没有执行完毕而导致PHP-CGI进程终止。(3) 502错误是php-fpm控制的,超时会终止cgi(4) 504是nginx报出的,代表nginx连接fastcgi超时2.codis的缺点是什么(1)master挂掉了,只能靠运维人员去维护(2)codis不保证数据一致性,不支持主从复制(3)非官方出品,后续升级没保障(4)codis不支持事务
3.mysql的死锁产生,还有如何防止(1)按同一顺序访问对象。(2)保持事务简短并在一个批处理中。(3)使用低隔离级别。(4)避免长事务,将事务拆解(5)设置锁超时等待innodb_lock_wait_timeout4.mysql分表的查询问题,怎么不遍历所有表做一个查询(1)借用redis或者数据表,存储映射关系,映射查询字段和分表的关系(2)找到分表之后,直接执行查询,组合数据即可5.php5.6和7.0的区别,写代码用到什么新特性了(1)PHP7.0之前出现的致命错误,都改成了抛出异常(2)增加了空结合操作符(??)。效果相当于三元运算符(3) PHP7.0新增了函数的返回类型声明(4)define 可以定义常量数组为什么php7比较快:1、存储变量的结构体变小,尽量使结构体里成员共用内存空间,减少引用,这样内存占用降低,变量的操作速度得到提升。2、字符串结构体的改变,字符串信息和数据本身原来是分成两个独立内存块存放,php7尽量将它们存入同一块内存,提升了cpu缓存命中率。 3、数组结构的改变,数组元素和hash映射表在php5中会存入多个内存块,php7尽量将它们分配在同一块内存里,降低了内存占用、提升了cpu缓存命中率。4、改进了函数的调用机制,通过对参数传递环节的优化,减少一些指令操作,提高了执行效率。6.laravel,yii,ci的区别,laravel的特点?控制反转?依赖注入?(1)laravel社区最活跃,支持的扩展也多(2)yii的配置文件比较麻烦,不过支持多种环境配置(3)laravel的路由比较强大,但是基于组件式,稍微臃肿点(4)yii的view和model层不太好用控制反转:和依赖注入配合使用,只不过是用容器去绑定依赖,这样相当于控制权给到了容器。依赖注入:不用在程序里实例化类,可以通过参数的形式注入进去ci:CI中的超级对象就是当前控制器对象,它提供了很多属性.($this)7.composer的自动加载机制(1)autoload机制 可以使得 PHP 程序有可能在使用类时才自动包含类文件,而不是一开始就将所有的类文件include进来,这种机制也称为 Lazy loading (惰性加载)。(2)单个autoload也不方便,难以维护,所以就出现了composer:composer 会找到符合 PR4 规范的第三方库的源将其加载到 vendor 目录下初始化顶级域名的映射并写入到指定的文件里写好一个 autoload 函数,并且注册到 spl_autoload_register()里8.redis的持久化,会持久化过期的key吗 (1)aof是以记录命令方式,所以如果还没过期,那么不会有变更的命令,如果过期,会在aof日志插入一条del命令。(2)rdb的话是内存快照方式,如果持久化时,key已经过期,那么不会持久化,如果在过期之前就已经持久化了,那么在恢复数据时,会判断key是否过期,如果过期不会导入。
9.redis和memcache的区别(1)存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);(2)灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;(3)redis数据结构更丰富(4)Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB
6、滴滴一面
1.go的协程比线程轻到哪里了?(1)协程在用户态进行上下文切换,耗时是线程的30/1。线程需要:1,000 ~ 1,500 纳秒(2)协程初始2kb,线程好几m(3)线程切换:cpu上下文(寄存器),私有的栈,线程状态等协程千幻:cpu上下文(寄存器)缺点:cpu无法实现抢占式调用协程2.算法题:堆排序升序----使用大顶堆降序----使用小顶堆(1)为什么升序要用大顶堆呢大顶堆的特点:每个结点的值都大于或等于其左右孩子结点的值,我们把大顶堆构建完毕后根节点的值一定是最大的,然后把根节点和最后一个元素(也可以说最后一个节点)交换位置,那么末尾元素此时就是最大元素了
3.go的runtime(1)在把用户写的程序翻译成可执行文件的过程中,把 runtime 代码塞进了可执行文件1)初始化全局变量,2)调用每个模块的init函数3)初始化 GC,以及初始化 Go scheduler4) 启用一个协程,调用用户写的 main 函数。
7、滴滴二面
1.php的autoload加载机制//根据类名找到文件$path = str_replace('_', '/', $class_name);//直接引入require_once $path . '.php';
2.php的数组扩容(1)有个参数,当删除的数量比较多时,先进行rehash计算,去掉删除的部分(2)删除比较少,空间不足,则扩容+rehash,申请2倍的空间,然后rehash计算3.redis的zset结构(1)数据量小于128或者存储的key小于64则为ziplist特点是内存连续,占用空间小(2)正常情况下是跳跃表,存在多级索引,第一层是双向链表结构由许多层结构组成。每一层都是一个有序的链表。最底层 (Level 1) 的链表包含所有元素。如果一个元素出现在 Level i 的链表中,则它在 Level i 之下的链表也都会出现(3)为什么用跳跃表不用红黑树(1)跳跃表底层是双向链表,适合做范围查询(2)跳跃表的修改,删除只需要更改相邻节点的指针,不需要重建树(3)跳跃表占用的内存比红黑树少一些(3)zet结构
1)由字典和跳跃表构成。字典让我们查询单个元素的时间复杂度是o(1),
跳跃表主要是按照分值对元素排序.范围查询的时候,时间复杂度是o(loginN)4.一个请求到php程序的过程(1)三次握手之后,请求建立连接,进入全连接队列,accept()函数可以取到(2)Nginx会按照FastCGI协议的消息格式发送数据,worker进程再按照协议多次read()数据并解析(3)词法语法分析,生成语言片段(4)zend引擎根据opcode调用机器指令(5)执行用户通过register_shutdown_function()注册的关闭函数(6)释放资源,清理符号表,销毁超全局变量,重置max_execution_time 等等5.一个请求到go程序的过程golang作为常驻进程, 请求第三方服务或者资源(http, mysql, redis等)完毕后,需要手动关闭连接, 否则连接会一直存在;(1)为什么请求之后要defer关闭https://www.cnblogs.com/lovezbs/p/13197587.html如果请求不手动关闭的话,每个请求都会创建两个goroutine,y分别去往这个连接写入请求(writeLoop函数)和读取响应(readLoop函数),且请求结束不会主动释放,会导致goroutine不断增加,导致内存泄露(2)go的链接复用问题在go的源码中特意指出,需要读取rep.body才能复用链接。有时候我们只读取header做判断,code不是200就返回错误,这样的话该链接就不会复用,导致出现大量的tcp : rst. --- go作为客户端1.创建http.Client对象client2.创建http.Request对象req3.发送请求client.do(req)4.关闭resp.Body.Close()---- 源码部分(1)client.do主要是参数校验,设置默认值,调用client.send(2)client.sendcookie的装载,获取Transport对象,调用http.send(3)http.send校验请求参数,超时取消(setRequestCancel)和请求事务: rt.RoundTrip(req)(4)client.setRequestCancel创建一个协程利用select chan机制阻塞等待取消请求(5)Transport.RoundTrip参数校验,获取缓存的或新建的连接(6)Transport.getConn连接池有空闲则取出空闲连接连接池无空闲则创建新连接达到最大数量则阻塞,等待空闲连接同时开启了两个goroutine,分别 读取response 和 写request--- go作为服务端是如何处理的http.HandleFunc("/hello", SayHello)(0) 首先调用Http.HandleFunc往DefaultServeMux的map[string]muxEntry中增加对应的handler和路由规则(1)http.ListenAndServe(":9090", nil) //设置监听的端口(2)ListenAndServe内部使用net包调用了 net.Listen("tcp", addr) 来监听端口--- 接收客户端请求(1)启动for循环,使 Listener 不断地接收来自客户端的请求,accept(2)给每个请求实例化一个conn,serve.NewConn(3)调用go c.serve启动协程,用户的每一次请求都是在一个新的 goroutine中服务,互相不影响--- 处理请求(1)分析请求,取出请求体resp,req(2)根据ServeMux 路由规则管理器map,判断请求分发给哪些handle(3)我们注册的函数会转化为handleFunc类型,然后通过handler.serveHttp(resp,req),从而实现请求处理6.gin框架的接口会开启协程吗
答:会的,参照上面的请求流程客户端:每次请求开启两个协程,负责读写服务端:每次开启一个协程处理请求7.外部怎么访问k8s的pod(1)nodeip: service设置为nodeip类型,集群外就可以使用K8s任意一个节点的IP加上30000端口访问该服务了,kube-proxy会自动将流量以轮询的方式转发给该service的每一个pod。(2)LoadBalancer:公有云提供的负载均衡器。任意节点的IP加30051端口访问服务 10.97.121.42:30051使用EXTERNAL-IP来访问,这是云供应商提供的负载均衡IP(3)ingressK8s管理的负载均衡容器,它的镜像包含一个nginx或HAProxy负载均衡器和一个控制器守护进程外部访问URL,访问该服务,入口是80端口,然后Ingress controller直接将流量转发给后端Pod,不需再经过kube-proxy的转发,比LoadBalance方式更高效8.k8s的服务发现(1)通过service实现的(2)etcd是干什么的https://zhuanlan.zhihu.com/p/96721097etcd 是一个分布式的、可靠的 key-value 存储系统,它用于存储分布式系统中的关键数据。使用Raft 一致性算法来实现分布式一致性服务注册:(1)提交服务配置,创建service对象,创建endpoint对象(2)DNS监控service变化,注册服务服务发现:(1)kube-proxy 监控ep变化,通过IPVS修改路由规则,去往service流量转向pod(2)服务通过DNS和service name 寻找 cluster ip (3)流量转发给 cluster ip,随后被路由规则转给 对应POD (4)kube-proxy 监控 pod,一旦发现 pod 服务变化,将会把新的 ip 地址更新到 service。kube-proxy 更新的存储在 etcd 里的映射关系(ep)9.dns解析步骤1)操作系统会先检查自己本地的hosts文件是否有这个网址映射关系2)如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存3)查找本地DNS服务器,也就是配置中的首选dns服务器4)转发模式:把请求转发到上一层dns服务器,不断转发5)非转发: 先发送到13台根服务器,根服务器返回顶级域名服务器的ip,客户端访问该ip,然后由顶级域名服务器进行下一级的查询6)为什么根域名只有13台?答:因为采用udp协议减小开销,dns规定512字节的传输上限,一次返回最多返回13个根域名记录
10.redis集群的分布式是什么样子的 不同的服务在不同的节点上。这些服务组合起来才是完整的功能,这就是分布式。
8、b站B部门二面
1.k8s的服务发现,服务注册,服务调用是为了什么服务注册:(1)提交服务配置,创建service对象,创建endpoint对象(2)DNS监控service变化,注册服务服务调用:(1)有两种方式,一种是RPC方式,另一种是事件驱动(Event-driven)方式,也就是发消息方式服务发现:(1)kube-proxy 监控ep变化,通过IPVS修改路由规则,去往service流量转向pod(2)服务通过DNS和service name 寻找 cluster ip (3)流量转发给 cluster ip,随后被路由规则转给 对应POD (4)kube-proxy 监控 pod,一旦发现 pod 服务变化,将会把新的 ip 地址更新到 service。kube-proxy 更新的存储在 etcd 里的映射关系(ep)2.k8s我们发布服务的时候,怎么进行一个平滑启动答:https://yuerblog.cc/2019/12/11/k8s-%E5%A6%82%E4%BD%95%E5%B9%B3%E6%BB%91%E5%8F%91%E5%B8%83%E5%BA%94%E7%94%A8%EF%BC%9F/上线:1)POD上线需要配置健康检查2)健康检查通过,service才会将POD加入endpoints列表,流量进入可以正常响应下线:1)POD下线时会在etcd中先标记POD状态为terminating退出中,其他相关联动资源会监听到变化并采取后续动作。2)先关闭监听,处理完已有请求,退出进程3.redis集群扩容的一个过程(1)添加节点(2)分配hash槽,可以全部重新分配,也可以指定节点分出一部分槽出来(3)槽迁移每个节点计算自己的槽,比如原来节点负责5000个槽,现在负责4000个,则把多余的1000迁移到新节点。主要是迁移槽上的key,4.mysql同时读写一行会数据,会触发锁吗对于普通SELECT语句,InnoDB不会加任何锁,所以读写同时进行没有问题,读为快照读,写为当前读5.go的map的底层结构(1)结构:散列表+bucket(2)底层一个数组arrindex = hash(key)arr[index] = struct{xxxx}(3)每个bucket中可以存储8个kv键值对,(4)hash值的低八位和bucket数组长度取余,定位到在数组中的那个下标,hash值的高八位存储在bucket中的tophash中,用来快速判断key是否存在,6.redis和mysql的强一致性如何实现 (1)两段式提交,引入一个协调者。事务A和事务B都分为准备和提交阶段,状态同步给协调者,任一步骤出问题则回滚(2)raft算法实现7.kafka在扩容的时候,怎么在不影响现有业务的情况下扩容(1)kafka新增节点,对其他节点来说是无感知的(2)在新节点上创建topic,或者迁移topic分区即可8.redis的热点key如何处理(1)收集热点key,比如自己写日志或者用redis提供的命令(2)加载到内存,直接在内存中读取(3)热点key分散,加个随机数进行分散,分散到多个redis机器,读的时候随机从有备份的redis上读取即可9.redis集群的脑裂如何避免min-slave解决。当脑裂之后,会有一个分区的slave升级为master,此时根据配置文件,当slave少于配置个数则停止写入。这样保证只有一个master提供写入,等网络恢复也不会有问题10.es的架构,index的内部实现https://blog.csdn.net/u013380694/article/details/101760607它可以将索引划分为多个分片,可以部署到集群中的任何一个节点,且每个分片都有副本,实现高可用(1)它允许水平切分内容卷。(2)它允许通过分片来分布和执行操作来应对日益增长的执行量。(3)一个索引就像数据库。而type就相当于每一张表,而mapping就相当于表的结构定义,定义了什么字段类型等往index的一个type里添加一行数据就叫做一个document每一个document有多个field查询:(1)客户端发送请求到协调节点(2)协调节点从分片上查询数据,由协协调节点进行聚合(3)合并数据,返回给客户端
9、回响科技一面
1.kafka多个分区怎么保证消息顺序(1)首先发送消息可以通过指定key+单分区实现(2)多个消费者消费的时候,可以自己对key取模,放入到队列中,开多线程去消费这些队列。队列内是有序的2.mysql在没有隔离级别的情况下,多线程修改一行数据可以吗(1)隔离级别是为了解决事务的并发问题,比如脏读,不可重复读,幻读问题等(2)当没有隔离级别的时候,多线程修改一行数据,就会出现:原始数据是0.线程1想+1,线程2也想+1,那么同时执行,结果是2,但是对于线程1来说,我只是想+1而已3.幂等性和线程安全?两个线程修改一个变量,为什么不行(1)确保在多线程访问的时候,我们的程序还能按照我们预期的行为去执行,那么就是线程安全。(2)两个线程修改一个变量是可以的,但结果可能不是我们想要的4.redis为什么要有单线程,除了锁还有其他原因吗(1)锁开销(2)不存在多进程或者多线程导致的切换而消耗CPU(3)无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善,同时给redis实例绑定cpu核即可发挥多核的优势5.rpc和http访问的区别在哪相同点:底层通讯都是基于socket,都可以实现远程调用,都可以实现服务调用服务不同点:(1)速度来看,RPC要比http更快,虽然底层都是TCP,但是http协议的信息往往比较臃肿(2难度来看,RPC实现较为复杂,http相对比较简单(3)如果对效率要求更高用rpc,灵活性通用性要求高用http(4)rpc是长连接,http是短连接,效率更高(5)rpc可以压缩消息,实现更极致的流量优化
6.mysql直接修改库存有什么问题?(1)没什么问题,主要是怕mysql承受不住太大的流量挂掉(2)常规方法是库存设置无符合,不能是负数,使用事务,代价是速度比较慢(3)我们可以考虑使用乐观锁,查询出version,修改的时候根据version来修改7.go中的锁是怎么实现的互斥锁:通过状态status和信号量来实现的。协程1加锁的话,lock=1协程2加锁的话,waiter=1,代表等下锁释放:协程A主要是通过释放信号量来通知协程b,此时协程B可以加锁自旋:加锁失败会持续请求加锁,不会立刻阻塞。是通过cpu的空转实现的,30个时钟周期8. redis的rdb和aof过程大概说一下
10、全民快乐一面
1.go常用的包有哪些,说说http和io包的函数
2.php的trait函数,trait引用的方法和原父类方法哪个优先级比较高父级使用trait关键字,当前类 通过use使用父类(1)代码复用,相当于copy了一份代码(2)类成员优先级为:当前类>Trait>父类3.mysql主从不一致的原因,在配置一样,不考虑网络因素的情况下(1)主从两台机器的负载不一致,线程忙不过来(2)max_allowed_packet ,主库设置的大,当有大sql的话,从库无法执行(3)自增键不一致 ,自增步长不一致导致(4)同步参数未设置 =1
4.go的channel怎么保证线程安全的(1)channel内部维护了一个互斥锁,来保证线程安全5.100W用户刷视频,怎么保证用户刷的视频不不重复
6.php安装扩展的步骤,编译的命令是哪个1. wget extension.tar.gz下载相应的扩展包并解压。2. cd extension/切换到扩展extension的目录中3. /php/bin/phpize 运行php安装目录下的phpize文件,这时候会在extension目录下生成相应的configure文件。4. /configure --with-php-config=/php/bin/php-config 运行配置,如果你的服务器上只是装了一个版本的php则不需要添加--with-php-config 。后面的参数只是为了告诉phpize要建立基于哪个版本的扩展。5. make && make install 编译模块7.唯一索引和主键索引的区别(1)一个表只能有一个主键索引,可以有多个唯一索引;(2)主键索引一定是唯一索引, 唯一索引不是主键索引;(3)主键可以与外键 构成 参照完整性约束, 防止数据不一致。
11、货拉拉二面
1.kafka保证消息顺序性写入生产者发送消息的send有四个参数(分区号、时间戳、key、headers),我们可以指定key,来保证消息都发送到同一个分区2.php的while..true常驻进程会造成什么影响 3.缓存击穿和缓存穿透(1)缓存击穿,是redis额热点key过期1)不给热点key设置过期时间2)互斥锁,发现无缓存,加锁去更新缓存(2)缓存穿透是redis+mysql都顶不住了1)参数校验,防止不存在的key2)布隆过滤器3)缓存空值或者默认值
12、b站B部门三面
1.接口网络超时如何排查 (1)代码层面1)下游sql等查询是否超时2)数据库连接是否满了,代码中是否出现死循环等占用大量的cpu和内存(2)网络层面1)运营商网络问题
2.kafka的offset和mysql的索引的区别kafka索引:(1)偏移量索引文件用来建立消息偏移量(offset)到物理地址之间的映射关系,方便快速定位消息所在的物理文件位置;(2)时间戳索引文件则根据指定的时间戳(timestamp)来查找对应的偏移量信息。查找步骤:(1)根据offset找到日志分段的索引文件(.index文件)(2)读取偏移量索引索引文件,使用二分找到最大索引项(3)读取日志分段文件并且从日志分段文件中顺序查找(.log文件)relativeOffset对应的消息区别:(1)kafka是系数索引,mysql是b+树索引(2)kafka维护索引使用了跳跃表结构,索引维护结构不会随便变动,有新索引文件才更新。mysql的索引树更新比较频繁(3)应用场景不同,kafka是主要是顺序写入,顺序读出,很少有检索的操作。3.x=1 and y>1 order by z如何建索引
13.好未来一面
1.服务间通信的实现微服务必须使用进程间通信机制来交互,微服务架构异步消息机制和同步请求/响应机制这两类 IPC 机制可用2.服务探针的实现存活探针:为了查看容器是否正在运行,如果返回false则重启pod就绪探针:查看容器是否准备好接受HTTP请求,通过则把流量发到pod上 存活探针和就绪探针被称作健康检查。3.进程,线程间的通信方式进程--------1)管道( pipe ):一般是父子进程通信2)信号量:主要作为进程间以及同一进程内不同线程之间的同步手段也是一种锁机制3)共享内存:最快的ipc通信4)套接字:可用于不同的进程通信。5)消息队列:由消息的链表,存放在内核中并由消息队列标识符标识线程----------------线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。1)锁机制:包括互斥锁、条件变量、读写锁2)信号量机制(Semaphore):包括无名线程信号量和命名线程信号量3)信号机制(Signal):类似进程间的信号处理
14、映客一面
1.手写lru2.mysql的acid分别是怎么实现的Atomicity)原子性: 事务是最小的执行单位,不允许分割。原子性确保动作要么全部完成,要么完全不起作用;(1)通过undo日志,事务回滚时能够撤销所有已经成功执行的sql语句(Consistency)一致性: 执行事务前后,数据保持一致;(1)一致性是事务追求的最终目标,前问所诉的原子性、持久性和隔离性,其实都是为了保证数据库状态的一致性。(Isolation)隔离性: 并发访问数据库时,一个事务不被其他事务所干扰。(1)四种隔离级别实现的
(Durability)持久性: 一个事务被提交之后。对数据库中数据的改变是持久的,即使数据库发生故障。(1)Innnodb有很多 log,持久性靠的是 redo log。(2)如果出现缓冲丢失,可以从redo logo日志中恢复3.go的syncmap怎么实现并发安全的(1)步骤a、过 read 和 dirty 两个字段将读写分离,读的数据存在只读字段 read 上,将最新写入的数据则存在 dirty 字段上b、读取时会先查询 read,不存在再查询 dirty,写入时则只写入 dirtyc、读取 read 并不需要加锁,而读或写 dirty 都需要加锁d、另外有 misses 字段来统计 read 被穿透的次数(被穿透指需要读 dirty的情况),超过一定次数则将 dirty 数据同步到 read 上e、对于删除数据则直接通过标记来延迟删除(2)原理sync.map实现就是依靠两张map对读操作和写操作分离,后续根据需要在把dirty map合入 read map中。4.tcp的timewait怎么产生的,如何防范作用:(1)保证服务器能收到最后一次ack(2)同时2msl能保证旧报文消失,防止旧报文出现在新的连接中防范:(1)服务器设置套接字:so_reuseaddr(2)短连接改成长连接(3)linux内核参数:net.ipv4.tcp_tw_reuse5.介绍项目的时候,最好是把技术栈各方面都详细的说一下6.插入100W数据,大概耗时多少,如何优化?批量插入的时候会影响其他操作吗,如何优化?7.redis的分布式锁在高并发情况下会出现什么问题(1)锁续约问题,可以用redisson的看门狗机制(2)锁超时时间一定要设置(3)根据value上锁,防止释放锁混乱(4)分布式场景下,master加锁之后挂掉,slave会成为新的master此时A客户端认为自己上锁了,B客户端也能获取到锁,会造成锁混乱使用redlock会好一些8.https到底是对称加密还是非对称加密?答:是非对称加密(公私钥) +对称加密(传输内容对称加密)1.客户端请求服务端,获取公钥。2.服务端生成公私钥,自己保存私钥(SK),将公钥(PK)发给客户端。3.客户端生成随机字符串key,通过公钥(PK)加密后发送给服务端。4.服务端拿到加密后的内容后,用自己的私钥(SK)进行解密,得到key,后续的过程都是通过密钥(key)来进行对称加密来传输。
15、小猪民宿
1.php的worker线程假死,如何重连的(1)首先,php-fpm假死一般是线程繁忙或者请求数过多,超时等原因,主要是修改配置文件,增加请求数量限制,超时时间等。(2)kill掉worker之后,master进程会自动创建一个work出来2.设计php框架的问题
3. mysql的查询优化器工作原理(1)主要是判断cost,cost包括扫描行数等(2)参照mysql拾遗
4.单机多少配置才能顶住1000qps参考:https://blog.csdn.net/weixin_34346099/article/details/88679411假如机器是4核8G:(1)同时处理的请求做多4个 (2) 假设一个进程30M,那么4048/30 = 135(留一些给mysql)(3) 假设一个请求200ms,那么1000qps要求T = (1000 / n ) * t总耗时:T一次处理请求:n每次请求时间:t 200ms(4) 根据计算可以得知,我们一次要处理200个请求才行首先我们的worker进程是足够的,其次是4核也够用(5 )其他需要注意的点1)mysql连接数 2) 服务器句柄限制, ulimit -n查看3)tcp的timewait影响,允许端口复用
5.压测需要注意的参数1)qps2) 请求处理时间3)
16.滴滴二面
1.一致性hash(1)对2的32次方取模,构造0-2的32次方哈希环(2)对服务器的IP或主机名作为关键字进行哈希(3)计算key的hash,计算出在哪个空间,顺时针往下寻找节点即可(4)为了防止数据分布不均匀,构造虚拟节点(5)节点宕机,只会影响不一部分数据,其他节点还能正常使用2.两个文件a和b里面都是id,求出不同的id (1)分治,hash(id)%1000,分成1000个小文件,a0...a99(2)此时a99中的id肯定也在b99中,文件就转化为了对小文件的求去重(3) 读取a0,构造hash表,再便遍历b0,如果a0中不存在则为不重复的id,放入新集合中即可4.myisam的应用场景特点:高性能读取,存储的有行数,无事务场景:(1)需要频繁count的场景(2)读多写少的场景
17.百度1-5面
大部分八股文跟上面雷同,只记录不同的
1.对于团队管理的理解
2.项目的架构设计,为什么这么设计
3.字符串中,中括号,大括号,小括号, 判断是否匹配(算法)
4.乱序数组,构建二叉树(算法)
三、后记
以上就是博主历时2个月的面试记录了。提醒大家一定要刷算法题,博主基本都是倒在算法题上面。其次面试看运气,不要在意,面就完了。
end
2021中大厂php+go面试题(2)相关推荐
- 2021中大厂php+go面试题(1)
一.前言 最近打算从二线去一线,借着远程面试盛行的机会,果断远程面了一圈,遇到的面试题也都记了下来,主要是php+go的部分面试题.部分问题附带答案,希望对大家找工作能有帮助. 首先面试都是从小公司到 ...
- 2021年最新大厂php+go面试题集(四)
持续更新,每天进步一点点... 微信公众号:码农编程进阶笔记 关注可获得更多的视频教程及面试技巧.问题或建议,请公众号留言! 22.回响科技一面 1.kafka多个分区怎么保证消息顺序(1)首先发送消 ...
- 2021大厂字节跳动笔试题(含答案)
2021字节跳动web工程师笔试题 第一题 [ {num: 12, city: 'beijing'}, {num: 56, city: 'shanghai'}, {num: 167, city: 'g ...
- 进大厂一条龙服务(Java核心面试知识点+一线大厂Java笔试面试题+月薪3万Java优秀简历模板),看这篇就够了
你有没有觉得Java_工程师竞争压力大.就业困难?不知道面试Java工程师应该准备些什么?.. 现在一切都解决了!你想要的干货知识和面试题统统在这,还有月薪3万Java优秀简历模板,快拿回去嚼烂吧! ...
- 【2021最新版】RabbitMQ面试题总结(32道题含答案解析)
文章目录 1.什么是rabbitmq? 2.为什么要使用rabbitmq? 3.使用rabbitmq的场景. 4.如何确保消息正确地发送至RabbitMQ?如何确保消息接收方消费了消息? 5.如何避免 ...
- (一)梳理前端知识体系,搞定大厂必考面试题
梳理前端知识体系,搞定大厂必考面试题 常见面试题 JS基础知识 变量类型和计算 原型和原型链 作用域和闭包 异步和单线程 运行环境 HTTP协议 总结 常见面试题 JS基础知识 变量类型和计算 typ ...
- 2022最新Spring相关大厂常问技术面试题大全 —— 金三银四好时机
Spring相关大厂常问面试题 1. 什么是 Spring 框架? 2. 列举一些重要的Spring模块? 3. @RestController 与 @Controller 的区别 4. 谈谈自己对于 ...
- linux sed面试题,【2021最新版】Linux面试题总结(48道题含答案解析)
文章目录 1.绝对路径用什么符号表示?当前目录.上层目录用什么表示?主目录用什么表示? 切换目录用什么命令? 2.怎么查看当前进程?怎么执行退出?怎么查看当前路径? 3.怎么清屏?怎么退出当前命令?怎 ...
- 2021年N1叉车司机免费试题及N1叉车司机考试总结
题库来源:安全生产模拟考试一点通公众号小程序 安全生产模拟考试一点通:N1叉车司机免费试题是安全生产模拟考试一点通生成的,N1叉车司机证模拟考试题库是根据N1叉车司机最新版教材汇编出N1叉车司机仿真模 ...
最新文章
- 使用spring initializr ( 4.快速创建springboot工程 )(入门结束)
- [恢]hdu 2014
- linux下使用automake、autoconf生成configure文件
- 生成pojo mysql_通过数据库表反向生成pojo类
- 2. Python3输入与输出
- ASP.NET中的AdRotator控件即广告控件的使用
- 一些有趣的三方开源库
- Android之Handler用法总结(1)
- Centos 7换源
- c语言回溯算法骑士周游,191-骑士周游回溯算法代码实现(1)
- php sqlserver08001,PHP连接sqlserver2008,怎么连接指定ip地址上的数据库
- python续行_python 控制台单行刷新,多行刷新
- Leetcode 303.区域和检索 - 数组不可变
- javascript 弹出层(警告框)的制作(css元素居中、javascript元素居中)
- PeopleSoft Rich Text Boxes上定制Tool Bars
- 手机微信和QQ接收到的文件路径
- Pidgin 插件法解决Ubuntu11.10 QQ
- java动作游戏教程_格斗游戏的动作设计和制作
- django mysql sql语句_Django中使用mysql数据库并使用原生sql语句操作
- numpy.meshgrid()理解
热门文章
- 论文查重的内容是哪些?
- 华为鸿蒙系统支持旧机型,华为鸿蒙系统2.0来了! 华为鸿蒙2.0系统支持手机机型...
- backgroundLinearGradient线性渐变制作折角效果
- linux安装GPU显卡驱动、CUDA和cuDNN库
- MongoDB——聚合管道之$match和$count操作
- PHP GD库文字生成图片及图片拼接
- 大疆图像算法面试流程
- 设计模式初探-观察者模式
- vs怎么配置c语言codemac,在Mac上使用vs-code快速上手c语言学习(入门文,老鸟退散)...
- 机器学习(八):CS229ML课程笔记(4)——生成学习,高斯判别分析,朴素贝叶斯