PHP面试

374 阅读9分钟

PHP

  • 循环数组的几种方式
    • foreach
    • array_map
    • array_walk
    • array_reduce
    • for
    • current next prev 相关的数组指针操作
  • 数组去重
    • array_unique
    • array_flip 交换两次key值 利用 php数组key只能唯一特性去重
  • 数组合并
    • array_merge 和 加号运算符都可以合并数组
    • array_merge 对字符串键名数据,后一个数组数据会重写前一个数组数据;而加号运算符不会重写
    • array_merge 对数字键名数据,不会重写前一个数组数据,而是做附加操作
  • 排序算法
    • 快速排序
    • 冒泡排序(比较两个相邻的元素,将值大的元素交换到右边)
    • 插入排序
    • 选择排序
  • cgi,fast-cgi和php-fpm的关系
    • cgi fast-cgi 都是通讯协议,cgi一个进程处理一个请求就会销毁,fast-cgi可以一个进程处理多个请求
    • php-cgi 是fast-cgi对于php写的一个管理器
    • php-fpm 是管理php-cgi的管理器
  • nginx+php-fpm原理
    • 用户访问网页,nginx接受请求,加载fast-cgi,把请求转发到9000端口,php-fpm接受到请求启动worker进程去处理请求,php-fpm处理完了返回给nginx,nginx再返回给浏览器
  • 魔术方法
    • __set() 在给不可访问属性赋值时会被调用
    • __get() 读取不可访问属性的值时会被调用
    • __iseet() 在对不可访问属性调用isset()或empty()会被调用
    • __unset() 当对不可访问属性调用unset()会被调用
    • __call() 当对象中调用一个不可访问方法时会被调用
    • __callStatic() 在静态上下文中调用一个不可访问的方法时,__callstatic会被调用
    • __sleep() 在被serialize()序列化时会被调用
    • __wakeup() 在被unserialize()反序列化会被调用
  • session和cookie的区别和优缺点
    • session存放在服务器,需要消耗服务器的内存或者缓存等等具体看存贮的工具
    • cookie存放在浏览器,用户是可以看见自己存放的信息的是不安全的
  • php的垃圾机制
    • php采用引用计数器制回收,就是说一个对象每被引用一次内部的计数器就会加1,当这个计数器为0时他就会被回收
  • 抽象类和接口类有什么区别
    • 对接口的继承使用implements,抽象类使用extends
    • 接口中不可以声明变量,但可以声明类常量.抽象类中可以声明各种变量
    • 接口没有构造函数,抽象类可以有
    • 接口中的方法只能为public,抽象类中的方法可以用public,protected,private修饰
    • 一个类可以继承多个接口,但只能继承一个抽象类

缓存

  • Redis持久化
    • aof 日志
    • rdb 磁盘
    • 通过rdb恢复数据比aof快,因为rdb是由二进制序列化形式保存的
  • 分布式锁
    • 以单进程模式运行的redis服务可以同时被分布式部署和运行的多个服务/应用/进程共享
    • redis的set指令支持在设置键值的同事设置过期时间,并且整个操作式原子性的,所以完全可以基于这个操作来实现分布式锁,待资源处理完成后,再通过 DEL 指令删除键值来释放锁
  • 内存上限后会启动基于 LFU 模式的 LRU 淘汰策略,将访问频次高的数据保存,将访问频率低删除
  • 缓存穿透、缓存击穿、缓存雪崩区别和解决方案
    • 缓存穿透指缓存和数据库都没的数据被用户不断发起请求,例如id为-1的数据,解决方式:中间件做验证对异常的请求可以做拦截,也可以对没查到的数据做为空的缓存
    • 缓存击穿指缓存中没有但数据库里有数据,由于没有缓存,或者缓存过期,同时直接访问数据库读取数据,引起数据库的压力瞬间增加,造成压力过大,解决方式:设置热点数据永不过期
    • 缓存雪崩,指多条数据缓存时间过期,直接访问数据库读取数据,与缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库,解决方法,过期时间设置随机,防止同一时间大量数据过期现象发生或者使用集群

nginx

  • nginx有两种模式,一种单进程模式,一种master-worker模式,master去管理worker进程.

设计模式

  • 五大原则
    • 里氏替换(在外边调用的时候,尽量用子类代替基类)
    • 依赖倒置(针对接口编程,而不是针对实现编程,对象本身所依赖的类由外部传入,不要由自己去创建)
    • 接口隔离(避免一个接口类里面要实现多个方法)
    • 单一职责原则(类的责任要单一)
    • 开闭原则(尽量在不修改原有代码的基础上进行扩展)

数据库

  • mysql的优化

    • 索引优化,字段在where,group by,order by 使用比较多的情况下建立索引
    • 避免数据重复度高的字段建立
    • 能建立组合索引的情况就尽量建立组合索引(用户登陆的账号密码组合索引例子)
    • Explain 去分析哪种索引方式更合适,避免隐式转化,or这种查询会造成索引丢失
    • 数据分区
    • 数据量比较大的情况下分表,分库
    • 堆硬件
    • 开启慢查询,对比较慢的sql 进行分析怎么优化,
    • 部分字段的冗余
    • 主从复制,读写分离 ...
  • MyISAM和InnoDb的差别

    • MyISAM不支持事务,InnoDb支持
    • MyISAM不支持行锁定,InnoDb支持
    • MyISAM不支持外键,InnoDb支持
    • InnoDb不支持全文索引,MyISAM支持
    • InnoDb必须要有主键 ...
  • 为什么在读多写少的场景下myisam更适合?

    • myisam的索引存储方式与innodb不同,myisam的存储方式是索引一个文件,数据一个文件,innodb是索引和数据都一个文件,在查询的时候 myisam找到对应的文件,文件就直接告诉你存储的数据,innodb是先找到主键,在根据主键去找对应的节点,节点上在保存对应的数据
  • ACID特性

    • 原子性 指数据库事务中一系列sql,要么全都执行成功,要么都执行失败,不存在部分成功部分失败得情况 undo日志去写每条更新操作的撤销语句保持原子性
    • 一致性 事务开始前和结束后,数据库得完整性约束和业务逻辑得一致性不能被破坏
    • 隔离性 不同事务之间得操作是相互隔离,事务A不应该影响事务B状态,并且通过锁得机制来保证隔离性
    • 持久性 事务一旦提交,数据就会被永久性的保存下来,数据库事务中已经提交的更新记录还没同步到磁盘,通过redo日志记录这些操作
  • 事务隔离级别

    隔离等级脏读不可重复读幻读
    未提交读(Read uncommitted)可能可能可能
    已提交读(Read committed)不可能可能可能
    可重复读(Repeatable read)不可能不可能可能
    可串行化(Serializable)不可能不可能不可能
    • 脏读 事务B读取到事务A修改但未提交的数据,就意味着产生了脏读,B事务修改了数据,未提交,A事务读取到 并且提交,A读取到脏数据,B回滚,A再次读取变回B未提交之前的数据
    • 不可重复读 事务B能够读取到事务A提交过修改数据,就意味发生了不可重复读 ,A事务更新数据,未提交,B事务读取数据 ,A事务提交,B事务在读取数据,数据和第一次读的不一致
    • 幻读 事务 B 先通过指定条件查询出一些记录,然后事务 A 又向该表插入了符合同样条件的记录;事务 B 再次按照同样条件查询时,能够把事务 A 插入的记录也读取出来,就意味着发生了幻读
  • mvcc多版本并发控制,通过版本链(undo日志中纪录链表)和readview(生成快照)实现

  • 死锁,针对同一条记录的更新,两个事务出现互相依赖,就可能出现死锁出现死锁后,通常有两种解决方式:

    • 配置死锁超时时间 MySQL 提供了一个 innodb_lock_wait_timeout 配置项
    • 发起死锁检测 MySQL 提供了一个 innodb_deadlock_detect 配置项用于设置是否开启死锁检测

业务场景

  • 高并发场景:
    • 前端 按钮请求控制 cdn
    • nginx限流 负载均衡,启用gzip
    • php代码缓存 队列形式 避免复杂查询
    • redis缓存层 限流
    • 数据库层 加锁 加事务 加机器 增加最大连接数上限 数据库长连接
    • 资料

框架

  • laravel中的依赖注入详情
    • 依赖注入,就是在本身对象说依赖的类由外部传入,减少依赖,在laravel中,依赖注入主要由ioc容器实现, ioc容器在框架加载时, 绑定好对象的所需要的对象,在使用的时候通过反射实例化, 依赖注入到我们用的对象中提供我们使用
  • 门面的实现
    • 调用魔术方法 __callStatic然后用ioc容器去实例化,再调用具体的方法,传递参数

linux

  • 进程通信的方式
    • 管道
    • 命名管道
    • 内存映射
    • 消息队列
    • 共享内存
    • 信号量
    • 信号
    • 套接字
    • 详情

想问的问题

  • 我接手的项目是什么样子,我需要负责什么,团队的组成,目前的技术栈,我能学习到什么
  • 岗位的晋升相关
  • 为了胜任这个岗位我还需要学习哪些技术知识?
  • 通过刚才和我沟通,您对我的评价是什么,您觉得我的优势和劣势是什么?