对一位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有什么异同

我觉得php是在运行的时候,才进行编译,他会比较慢吧。
go和Java都是编译完后才执行

5、说说你在项目上有什么出色的表现? 我的说是我用时间切分进行算法上数据的调优

我觉得自己排查问题的能力,还是可以的。目前自己在排查问题方面还是可以的。

  1. 举例:iOS客户端的问题。没有上报数据。并通过日志去过滤信息,然后给对方回传。
  2. 安卓端的问题,取的设备信息不对
  3. 我这边消费者报错了,是因为rabbitmq出现了误报。每次heartbeat设置的时间太短了,为5s。后来设置为60s后,问题解决。

6、对于你们这个架构你觉得还有什么可以优化的

目前我的系统的话,在高并发上处理的不够。比如redis的话,我只使用了一台,目前只用了一台radis,对于redis异常情况没有进行处理设计。redis没有使用集群
MySQL的话,数据量已经比较大了,目前还没有做分库分表
我这边还没有做一些精细化的数据分析

7、redis单线程结构有什么优势?有什么问题?

主要优势单线程,避免线程切换产生静态消耗,缺点是容易阻塞,虽然redis使用io复用epoll和输入缓冲区把命令按照队列先进先出输入等等

避免了因为cpu切换导致的性能消耗,把并行请求转换为了串行请求。可能会出现堵塞的情况。但是因为优化了底层的数据结构,执行起来的效率还是很高的。

8、你觉得针对redis这些缺点那些命令在redis上不可使用?

比如keys、hgetall等等这些命令 建议用scan等等 这方面阐述

keys hgetall 会进行堵塞。建议使用scan来进行分页查询。

9、你觉得为什么项目中没有用mysql而用了es,redis在这里到底起到了什么作用?因为架构上这里理解不清楚,最后回答自己都觉得有漏洞了

10、你觉得redis什么算有用?

命中缓存,存储静态数据,减少对数据库的访问次数,加快接口的响应

有用?是说存进去了还是说命中缓存?最后把缓存命中率是什么说了一遍

11、看你上面写的开始学习go,你说说GO这边组合模式用PHP是怎么实现的? 组合....我都没学到

go基本是使用了组合的概念,减少了继承。通过类型来给对象设置不同的数据。在struct的里面,设置了对象的属性。

就是依赖注入吧。

12、如果产品这里在你导出大文件的情况下,太占资源,你该怎么办?

断点续传

批量导出

深信服

1 如果打开页面慢的话,怎么排查

  1. 是否是数据库的问题,比如没有命中索引,没有加索引,或者自己的SQL写的有问题
  2. 自己的程序是否有问题,是否是for循环过多。因为之前的话,每次循环插入SQL导致自己的程序执行很慢,所以后来就是改成500条一次。执行时间加快了很多。
  3. 是否是下游的服务问题
  4. 是否是硬件出了问题
  5. 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区别

  1. 每次运行文件都需要对文件进行编译和处理
  2. include 和require的报错级别不一样。include是warning,require是error级别

12 =和区别

=== 会进行类型的校验

13 date函数怎么插入上周时间

date("Y-m-d H:i:s", strtotime(" -1 week"))

作业帮:

1、三次握手、四次挥手,为什么time_wait,2MSL具体多长时间

  1. 三次握手,客户端发起握手请求,将syn设置为1,sequence number 为x,然后客户端进入syn_send状态。等待服务器的确认。
  2. 服务器端接收syn请求,需要对这个syn进行确认,设置ack为x+1, 自己还要发送syn信息,sequence number为y。服务器将上述所有信息都发送放到一个报文段,发送给客户端,此时服务器进入sys_recv状态,
  3. 客户端接收服务器的syn+ack,然后将sequence number 设置为y+1,然后向服务器发送ack报文段,等这个报文发送完毕以后,客户端和服务器都进入进入established状态

四次挥手

  1. 第一次分手:客户端向服务器发送关闭请求,此时客户端进入fin_wait_1阶段。表示客户端没有数据要发送给服务器端了
  2. 第二次分手:服务器接收到请求以后会发送一个ack,表示自己受到了,然后服务器端进入closed_wait状态。客户端会进入fin_wait_2状态
  3. 第三次分手:服务器在向客户端发送fin请求,同时服务器进入last_ack状态
  4. 第四次分手:客户端向服务器发送ack请求。然后客户端进入time_wait状态。主机2接收到请求之后,就关闭连接。客户端等待2msl之后没有收到服务器端的回复之后,就认为服务器正常关闭,那么客户端也就可以关闭连接了。然后就进入closed状态。

2、B+树和B树,联合索引等原理

B+树的话,叶子节点存储的是索引+数据。B树的话,所有节点存储的是数据的地址,查询的时候需要在内部节点和叶子节点之间来查询数据

B+树 叶子节点存储的是数据,而且叶子节点是一个双向链表,在叶子节点之间顺序查找会比较快。

3、自己项目数据库表是怎么样子的

4、一般项目PHP起几个进程

php-fpm有三种模式

  1. static: 这种方式比较简单,在启动时master按照pm.max_children配置fork出相应数量的worker进程,即worker进程数是固定不变的
  2. 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数
  3. ondemand: 这种方式一般很少用,在启动时不分配worker进程,等到有请求了后再通知master进程fork worker进程,总的worker数不超过pm.max_children,处理完成后worker进程不会立即退出,当空闲时间超过pm.process_idle_timeout后再退出

5、项目上线后有几个PHP服务器,单服务器出故障怎么处理 计算、存储、业务

6、网站打开慢了,你自己怎么处理

  1. 是否是数据库的问题,比如没有命中索引,没有加索引,或者自己的SQL写的有问题
  2. 自己的程序是否有问题,是否是for循环过多。因为之前的话,每次循环插入SQL导致自己的程序执行很慢,所以后来就是改成500条一次。执行时间加快了很多。
  3. 是否是下游的服务问题
  4. 是否是硬件出了问题
  5. 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防护的是什么

  1. 服务器将自己的公钥发送至ca,然后ca通过数据加密,返回给服务器端公钥证书。
  2. 服务器将公钥证书发送给客户端。客户端拿着公钥证书去ca进行验证,验证通过后获取公钥。
  3. 客户端生成一个随机的秘钥,通过公钥加密发送给服务器,然后服务器获取到秘钥后,双方使用对称加密去进行通信。

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

  1. 键(key):用于操作数据的标示,例如PHP数组中的索引,或者字符串键等等。
  2. 槽(slot/bucket):哈希表中用于保存数据的一个单元,也就是数据真正存放的容器。
  3. 哈希函数(hash function):将key映射(map)到数据应该存放的slot所在位置的函数。
  4. 哈希冲突(hash collision):哈希函数将两个不同的key映射到同一个索引的情况。
获取一个值,应该是hash取模。

3、foreach为什么比for循环快

因为foreach的话,有一个next指针能指向下一个元素的地址。for的话,还得需要重新hash计算吧。

4、php的fpm进程管理器的三种模式,优缺点是什么

  1. static: 这种方式比较简单,在启动时master按照pm.max_children配置fork出相应数量的worker进程,即worker进程数是固定不变的
  2. 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数
  3. 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怎么解决惊群现象的,区别呢?

  1. cgi 通用网关接口(Common Gateway Interface)
  2. fast-cgi 常驻(long-live)型的 CGI
  3. cli 命令行运行 (Command Line Interface)
  4. 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、进程和线程区别,什么时候用多进程什么时候用多线程

进程
  1. 资源分配的最小单位
  2. 进程拥有独立的地址空间
  3. 进程间通信通过信号量,信号、共享内存、消息传递、管道、队列
  4. 进程由操作系统调度
  5. 多进程方式比多线程稳定
线程
  1. 程序执行的最小单元。CPU调度的基本单位
  2. 线程来自于进程,一个进程下可以产生多个线程
  3. 每个线程都有自己一个栈,不共享栈,但多个线程能共享同一个属于进程的堆
  4. 线程共享内存
  5. 线程消耗低于进程
  6. 某个线程产生致命错误会导致进程奔溃
  7. 线程间读写变量存在锁的问题处理起来相对麻烦

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

  1. SQL注入

htmlspecialchars_decode()    把一些预定义的 HTML 实体转换为字符。

htmlspecialchars()    把一些预定义的字符转换为 HTML 实体。

strip_tags() 剥去字符串中的 HTML 和 PHP 标签。

  1. xss

htmlspecialchars()

strip_tags()

  1. csrf

使用token

http_only

使用referer 验证,只能使用原来的网址进行验证

3、项目开发怎么迅捷

敏捷开发

4、设计模式的使用

5、mysql如果发生了抖动,怎么排查问题

是否是io刷盘速度设置的不对。

  1. redolog满了需要刷盘
  2. 内存满了需要刷盘
  3. mysql处在空闲阶段,就刷盘
  4. 要关机了就刷盘

6、你能说一下nginx的日志能排查些出什么问题

  1. 请求信息,报错日志

7、你的以后目标是什么,如何持续学习,你认为的架构师是什么样子的

  1. 持续学习。

二面:

1、怼项目

2、设计一个限流的算法

3、平常redis用的多的数据结构是什么,跳表实现,怎么维护索引,当时我说是一个简单的二分,手写二分算法,并且时间复杂度是怎么计算出来的 (2的k次方等于n k等于logn)

4、设计模式用了哪些,手写出来

5、mysql的索引底层,还有explain每个字段的介绍,以及type类型都有哪些,分别都代表什么意思

6、php的话平常如果碰到不会的函数,你是怎么解决的?

看手册

7、你有什么要问我的

image

#社招##360公司##面经#
全部评论
哦豁!大佬加油鸭
1 回复
分享
发布于 2020-03-09 18:40
** 这也太强了
点赞 回复
分享
发布于 2020-03-26 13:30
阿里巴巴
校招火热招聘中
官网直投

相关推荐

3 31 评论
分享
牛客网
牛客企业服务