对一位PHP大佬面试题的学习
对一位PHP大佬面试题的学习
https://www.nowcoder.com/discuss/359186
360奇安(本公司) 天擎部门面试:
1、redis的sentinel上投票选举的问题 raft算法
当一定数量的子节点同意之后,就可以选举新的子节点。
2、脑裂问题怎么处理
3、php导出,如果存在把内存打爆,怎么处理的
ini_set("memory_limit", '1024');
4、你觉得PHP相对比JAVA或者GO有什么异同
5、说说你在项目上有什么出色的表现? 我的说是我用时间切分进行算法上数据的调优
我觉得自己排查问题的能力,还是可以的。目前自己在排查问题方面还是可以的。
- 举例:iOS客户端的问题。没有上报数据。并通过日志去过滤信息,然后给对方回传。
- 安卓端的问题,取的设备信息不对
- 我这边消费者报错了,是因为rabbitmq出现了误报。每次heartbeat设置的时间太短了,为5s。后来设置为60s后,问题解决。
6、对于你们这个架构你觉得还有什么可以优化的
7、redis单线程结构有什么优势?有什么问题?
避免了因为cpu切换导致的性能消耗,把并行请求转换为了串行请求。可能会出现堵塞的情况。但是因为优化了底层的数据结构,执行起来的效率还是很高的。
8、你觉得针对redis这些缺点那些命令在redis上不可使用?
比如keys、hgetall等等这些命令 建议用scan等等 这方面阐述
keys hgetall 会进行堵塞。建议使用scan来进行分页查询。
9、你觉得为什么项目中没有用mysql而用了es,redis在这里到底起到了什么作用?因为架构上这里理解不清楚,最后回答自己都觉得有漏洞了
10、你觉得redis什么算有用?
命中缓存,存储静态数据,减少对数据库的访问次数,加快接口的响应
有用?是说存进去了还是说命中缓存?最后把缓存命中率是什么说了一遍
11、看你上面写的开始学习go,你说说GO这边组合模式用PHP是怎么实现的? 组合....我都没学到
go基本是使用了组合的概念,减少了继承。通过类型来给对象设置不同的数据。在struct的里面,设置了对象的属性。
就是依赖注入吧。
12、如果产品这里在你导出大文件的情况下,太占资源,你该怎么办?
断点续传
批量导出
深信服
1 如果打开页面慢的话,怎么排查
- 是否是数据库的问题,比如没有命中索引,没有加索引,或者自己的SQL写的有问题
- 自己的程序是否有问题,是否是for循环过多。因为之前的话,每次循环插入SQL导致自己的程序执行很慢,所以后来就是改成500条一次。执行时间加快了很多。
- 是否是下游的服务问题
- 是否是硬件出了问题
- iostat top查看cpu 内存占用情况
2 怎么实现商城的商品推荐系统
3 sql语句 求一个成绩表中分数超过60的人的科目
select subject from table where score > 60;
4 innodb和myisam有什么区别
- innodb 是行锁,myisam是表锁
- innodb支持事务,myisam不支持事务,非事务安全
- innodb 主键的叶子节点存储的是数据,myisam叶子节点存储的是数据的地址,索引和数据时分开存储的。
- innodb聚集索引存储数据行本身,普通索引存储的是主键
5 反转字符串
<?php function getRev($str,$encoding="utf-8"){ $new_str = ""; $str_len = mb_strlen($str); for ($i = $str_len-1; $i >=0; $i--) { $new_str .= mb_substr($str, $i, 1, $encoding); } return $new_str; } $str = "hello,world;你好,世界"; $new_str = getRev($str); print_r($new_str);
6 php的date参数
7 mysql的注入,怎么处理
- PDO预处理就能过滤。
- 还有就是对输入进行转义
8 平常在公司都处理什么工作的
9 一个sql语句不使用大于小于号中确定范围[ 60,80]
11 include和require区别
- 每次运行文件都需要对文件进行编译和处理
- include 和require的报错级别不一样。include是warning,require是error级别
12 =和区别
=== 会进行类型的校验
13 date函数怎么插入上周时间
date("Y-m-d H:i:s", strtotime(" -1 week"))
作业帮:
1、三次握手、四次挥手,为什么time_wait,2MSL具体多长时间
- 三次握手,客户端发起握手请求,将syn设置为1,sequence number 为x,然后客户端进入syn_send状态。等待服务器的确认。
- 服务器端接收syn请求,需要对这个syn进行确认,设置ack为x+1, 自己还要发送syn信息,sequence number为y。服务器将上述所有信息都发送放到一个报文段,发送给客户端,此时服务器进入sys_recv状态,
- 客户端接收服务器的syn+ack,然后将sequence number 设置为y+1,然后向服务器发送ack报文段,等这个报文发送完毕以后,客户端和服务器都进入进入established状态
四次挥手
- 第一次分手:客户端向服务器发送关闭请求,此时客户端进入fin_wait_1阶段。表示客户端没有数据要发送给服务器端了
- 第二次分手:服务器接收到请求以后会发送一个ack,表示自己受到了,然后服务器端进入closed_wait状态。客户端会进入fin_wait_2状态
- 第三次分手:服务器在向客户端发送fin请求,同时服务器进入last_ack状态
- 第四次分手:客户端向服务器发送ack请求。然后客户端进入time_wait状态。主机2接收到请求之后,就关闭连接。客户端等待2msl之后没有收到服务器端的回复之后,就认为服务器正常关闭,那么客户端也就可以关闭连接了。然后就进入closed状态。
2、B+树和B树,联合索引等原理
B+树的话,叶子节点存储的是索引+数据。B树的话,所有节点存储的是数据的地址,查询的时候需要在内部节点和叶子节点之间来查询数据
B+树 叶子节点存储的是数据,而且叶子节点是一个双向链表,在叶子节点之间顺序查找会比较快。
3、自己项目数据库表是怎么样子的
4、一般项目PHP起几个进程
php-fpm有三种模式
- static: 这种方式比较简单,在启动时master按照pm.max_children配置fork出相应数量的worker进程,即worker进程数是固定不变的
- dynamic: 动态进程管理,首先在fpm启动时按照pm.start_servers初始化一定数量的worker,运行期间如果master发现空闲worker数低于pm.min_spare_servers配置数(表示请求比较多,worker处理不过来了)则会fork worker进程,但总的worker数不能超过pm.max_children,如果master发现空闲worker数超过了pm.max_spare_servers(表示闲着的worker太多了)则会杀掉一些worker,避免占用过多资源,master通过这4个值来控制worker数
- ondemand: 这种方式一般很少用,在启动时不分配worker进程,等到有请求了后再通知master进程fork worker进程,总的worker数不超过pm.max_children,处理完成后worker进程不会立即退出,当空闲时间超过pm.process_idle_timeout后再退出
5、项目上线后有几个PHP服务器,单服务器出故障怎么处理 计算、存储、业务
6、网站打开慢了,你自己怎么处理
- 是否是数据库的问题,比如没有命中索引,没有加索引,或者自己的SQL写的有问题
- 自己的程序是否有问题,是否是for循环过多。因为之前的话,每次循环插入SQL导致自己的程序执行很慢,所以后来就是改成500条一次。执行时间加快了很多。
- 是否是下游的服务问题
- 是否是硬件出了问题
- iostat top查看cpu 内存占用情况
7、WAF有几台机器
8、你这个千万级别数据怎么处理的,分库分表?
9、PHP弱语言类型怎么实现的
zval根据type来决定value的类型
10、PHP和JAVA区别
11、你们这边redis集群是怎么样子的
12、怎么查看CPU负载,怎么查看一个客户下有多少进程
13、怎么将Kafka数据导入数据库,如果防止重复消费,以及如果防止数据不丢失,redis分布式锁和redlock以及zokkerper锁的实现区别,优点是什么
总结一下:狂怼项目,对项目中细节都问的特别细,简称深入灵魂的拷问
顺丰 一面:
1、狂怼项目,然后问一些项目相关的知识,比如自己双写不一致问题,是写频繁还是读频繁,如果写频繁为什么还需要缓存,如果我要做的就是要修改数据库然后修改redis,怎么解决不一致问题。我的回答是redis分布式锁,然后讨论分布式锁以及redlock锁等等
2、http和https区别,非对称加密的过程
3、mysql的悲观锁和乐观锁区别和应用,ABA问题的解决
4、mysql索引的底层B+树,说说为什么使用B+树,跟红黑树有什么去呗
树的查询时间跟树的高度有关,B+树是一棵多路搜索树可以降低树的高度,提高查找效率。
5、事务的可重复读幻读是什么情况,怎么解决幻读
6、http的一些字段,就你知道的回答一些
7、三次握手和四次挥手、为什么需要三次握手L
二面:
1、http和https的区别,CA证书的优缺点,https抓包的时候出现的是什么,https防护的是什么
- 服务器将自己的公钥发送至ca,然后ca通过数据加密,返回给服务器端公钥证书。
- 服务器将公钥证书发送给客户端。客户端拿着公钥证书去ca进行验证,验证通过后获取公钥。
- 客户端生成一个随机的秘钥,通过公钥加密发送给服务器,然后服务器获取到秘钥后,双方使用对称加密去进行通信。
https防护的是数据,防止数据被窃听。
2、apache和nginx的区别
3、nginx的epoll模型的介绍以及io多路复用模型
4、狂怼项目
5、算法题,快排和一个变种的归并
今日头条
一面:
1、说说你的项目架构图以及数据走向
2、PHP源码的数组的排序是在底层源码哪里体现的。
3、PHP的垃圾回收机制
4、状态码 499、502、504这些是在什么场景出现的,你有在实际项目中看到吗
499 就是客户端请求时间过程, 然后NGINX主动关闭了请求
502 一般是fpm配置有问题
502 一般是fpm配置有问题。比如请求超时。max_children和request_terminate_timeout。max_children最大子进程数 超过了php-fpm 的最大响应数,就会出现502.netstat可以查看连接数。一个php-cgi消耗的内存在20M左右,php-cgi所占用的内存为20M*max_request数量。为单个请求的超时时间(request_terminate_timeout)。当数据库连接超时,或者大量请求超时的时候,会出现502.
504 一般是NGINX的问题
504一般是NGINX配置有问题。Gateway Time-out。fastcgi_connect_timeout、fastcgi_send_timeout、fastcgi_read_timeout、fastcgi_buffer_size、fastcgi_buffers、fastcgi_busy_buffers_size、fastcgi_temp_file_write_size、fastcgi_intercept_errors。fgi缓冲区太小,会导致504.
5、PHP如果一个页面超时,怎么查看是哪一个接口超时的。这里查看慢查询日志
6、PHP的FPM进程管理器的三种管理模式都有什么
7、比如你的服务器,一个小时前的cpu占用率到达百分之百,现在恢复正常,你怎么排查出来之前是什么原理导致的(这个可以看nginx的日志)
8、mysql的索引底层,以及覆盖索引和普通索引的区别,你平常怎么看你的SQL有没有使用到索引(我说的explain执行计划),如果使用了覆盖索引,在执行计划上面那个字段会体现,显示的是什么
9、redis的缓存穿透,布隆过滤器是怎么设计的
滴滴
一面:
1、两个手写算法题,一个复杂链表的翻转,一个字符串累加和
2、php的hashtable
- 键(key):用于操作数据的标示,例如PHP数组中的索引,或者字符串键等等。
- 槽(slot/bucket):哈希表中用于保存数据的一个单元,也就是数据真正存放的容器。
- 哈希函数(hash function):将key映射(map)到数据应该存放的slot所在位置的函数。
- 哈希冲突(hash collision):哈希函数将两个不同的key映射到同一个索引的情况。
3、foreach为什么比for循环快
因为foreach的话,有一个next指针能指向下一个元素的地址。for的话,还得需要重新hash计算吧。
4、php的fpm进程管理器的三种模式,优缺点是什么
- static: 这种方式比较简单,在启动时master按照pm.max_children配置fork出相应数量的worker进程,即worker进程数是固定不变的
- dynamic: 动态进程管理,首先在fpm启动时按照pm.start_servers初始化一定数量的worker,运行期间如果master发现空闲worker数低于pm.min_spare_servers配置数(表示请求比较多,worker处理不过来了)则会fork worker进程,但总的worker数不能超过pm.max_children,如果master发现空闲worker数超过了pm.max_spare_servers(表示闲着的worker太多了)则会杀掉一些worker,避免占用过多资源,master通过这4个值来控制worker数
- ondemand: 这种方式一般很少用,在启动时不分配worker进程,等到有请求了后再通知master进程fork worker进程,总的worker数不超过pm.max_children,处理完成后worker进程不会立即退出,当空闲时间超过pm.process_idle_timeout后再退出
5、php fpm进程master进程和worker进程分别的责任是什么
master负责监听来自web server 的请求,然后将该请求指定给worker
worker负责执行请求,然后将执行的结果,返回给web server
6、php常用的运行模式有哪些,fpm和cli运行生命周期是什么和fpm模式中在进行fcgi-accept-request中如何解决惊群现象的,你知道nginx怎么解决惊群现象的,区别呢?
- cgi 通用网关接口(Common Gateway Interface)
- fast-cgi 常驻(long-live)型的 CGI
- cli 命令行运行 (Command Line Interface)
- mod_php模式 (apache等web服务器运行的模块模式)
7、redis数据结构是哪些,然后问我有序集合的底层,跳表的实现,时间复杂度以及如何加一个数据
8、redis字典的底层hashtable,以及和php的数组底层hashtable对比,以及redis的rehash过程,以及优化渐变式rehash
9、mysql索引底层数据结构,为什么使用b+树不用b树
B+树的话,叶子节点存储的是索引+数据。B树的话,所有节点存储的是数据的地址,查询的时候需要在内部节点和叶子节点之间来查询数据
B+树 叶子节点存储的是数据,而且叶子节点是一个双向链表,在叶子节点之间顺序查找会比较快。
10、mysql的数据页空洞是怎么造成的,如果解决,索引是局部还是全局的
alter table t engine = innodb; 可以重建表。可用于重建表。
11、mysql事务都有什么,以及幻读因为什么造成的
原子性
一致性
隔离性
持久性
幻读是在可重复读的隔离级别下,在一个事务中,两次读取的数据不一致。
你有什么要问我的
二面
1、一个变种的纸牌算法(因为之前不知道,自己推,解出来将近半个小时)
2、画出项目架构图,以及数据流向,然后怼项目
3、进程和线程区别,什么时候用多进程什么时候用多线程
进程
- 资源分配的最小单位
- 进程拥有独立的地址空间
- 进程间通信通过信号量,信号、共享内存、消息传递、管道、队列
- 进程由操作系统调度
- 多进程方式比多线程稳定
线程
- 程序执行的最小单元。CPU调度的基本单位
- 线程来自于进程,一个进程下可以产生多个线程
- 每个线程都有自己一个栈,不共享栈,但多个线程能共享同一个属于进程的堆
- 线程共享内存
- 线程消耗低于进程
- 某个线程产生致命错误会导致进程奔溃
- 线程间读写变量存在锁的问题处理起来相对麻烦
4、mysql索引底层数据结构,以及redis的hashtable和建遍式rehash过程
B+树。查找速度比较稳定。
5、mysql的锁都有什么,怎么使用的,怎么结果mysql的可重复读的幻读,MyISAM和innodb区别,还有innodb的crash-safe,以及redo log 和binlog的2pc提交方式,MVCC的实现原理,一致性视图和undo log
行锁,表锁。
行锁的话,
有共享锁和排它锁。 lock in share mode for update
innodb的crash-safe
有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe。要理解 crash-safe 这个概念,可以想想我们前面赊账记录的例子。只要赊账记录记在了粉板上或写在了账本上,之后即使掌柜忘记了,比如突然停业几天,恢复生意后依然可以通过账本和粉板上的数据明确赊账账目。
redo log 和binlog的2pc提交方式
执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;
否则,需要先从磁盘读入内存,然后再返回。
执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。
然后告知执行器执行完成了,随时可以提交事务。执行器生成这个操作的 binlog,并把 binlog 写入磁盘。 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。
6、你的领导怎么评价你、你的同事怎么评价你、你自己怎么评价你自己、有什么优缺点、短期的目标计划呢、怎么改进自己的优缺点
腾讯:
一面:
1、怼项目,然后根据CAP理论设计出比当前解决方案更好的,如何架构
2、你的PHP是怎么做安全处理的,比如SQL注入、xss、csrf
- SQL注入
htmlspecialchars_decode() 把一些预定义的 HTML 实体转换为字符。
htmlspecialchars() 把一些预定义的字符转换为 HTML 实体。
strip_tags() 剥去字符串中的 HTML 和 PHP 标签。
- xss
htmlspecialchars()
strip_tags()
- csrf
使用token
http_only
使用referer 验证,只能使用原来的网址进行验证
3、项目开发怎么迅捷
敏捷开发
4、设计模式的使用
5、mysql如果发生了抖动,怎么排查问题
是否是io刷盘速度设置的不对。
- redolog满了需要刷盘
- 内存满了需要刷盘
- mysql处在空闲阶段,就刷盘
- 要关机了就刷盘
6、你能说一下nginx的日志能排查些出什么问题
- 请求信息,报错日志
7、你的以后目标是什么,如何持续学习,你认为的架构师是什么样子的
- 持续学习。
二面:
1、怼项目
2、设计一个限流的算法
3、平常redis用的多的数据结构是什么,跳表实现,怎么维护索引,当时我说是一个简单的二分,手写二分算法,并且时间复杂度是怎么计算出来的 (2的k次方等于n k等于logn)
4、设计模式用了哪些,手写出来
5、mysql的索引底层,还有explain每个字段的介绍,以及type类型都有哪些,分别都代表什么意思
6、php的话平常如果碰到不会的函数,你是怎么解决的?
看手册
7、你有什么要问我的
#社招##360公司##面经#