php

php7 为什么比 php5 快

减少内存分配次数,多使用栈内存,缓存数组hash值,字符串解析成参数改为宏展开,使用大块连续内存代替小块碎片内存等等。

PHP7卓越性能背后的原理有哪些? - 韩天峰的回答 - 知乎 https://www.zhihu.com/question/38148900/answer/75115687

php 的变量以什么数据结构保存在内存里

php 内存分为堆内存、栈内存、代码段、初始化静态段。

栈内间段:是存储占用相同空间长度并且占用空间小的数据类型的地方,比如说整型1,10,100,1000,10000,100000 等等,在内存里面占用空间是等长的,都是64 位4 个字节。存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。所以在栈空间的数据都是可以通过代码手动进行释放。

堆空存段:数据长度不定长,而且占有空间很大的数据类型的数据。在堆内存是里是不可以直接存取的内存,堆内存存储的是数组和对象(其实数组就是对象)。凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,最后通过垃圾回收机制去实现垃圾回收。对于我们的对象来数就是一种大的数据类型而且是占用空间不定长的类型,所以说对象是放在堆里面的,但对象名称是放在栈里面的,这样通过对象名称就可以使用对象。

https://cloud.tencent.com/developer/article/1162322

php的垃圾回收

采用计数法,当一个变量增加一个引用的时候,计数加一,没有引用的时候清理掉

接口和抽象类的区别

  1. 抽象类可以有构造方法,接口中不能有构造方法。
  2. 接口中每个方法都只有声明而没有实现,其中的每个方法实现类必须要实现;而抽象类中只需要实现抽象方法,其它方法可以选择性的实现
  3. 接口中只能声明public的方法,不能声明private和protected的方法,不能对方法进行实现,也不能声明实例变量;但是抽象类中可以
  4. 一个类可以实现多个接口,但是继承一个抽象类。二者在应用方便也有一定的区别:接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方法进行权限判断,记录访问日志和异常处理,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中玩具城权限判断,记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码
  5. 抽象类需要继承,用extends,而接口需要实现,用implements
  6. 一个类可以实现多个接口,但只能继承一个抽象类

public private protect

  • public 外部可调用,子类可调用
  • protect 外部不能调用,子类可调用
  • private 外部不能调用,子类不能调用

self:: static::

self::调用父类,static::调用当前类(子类)

数据库

redis 跳表的数据结构

简单的来说就是自带了一个跳跃的索引,比如数据是123456789,那么跳表的一级索引可以是148,二级索引是14

https://www.jianshu.com/p/d12389b80a19

redis key 过期策略

  1. 定期删除:每一段时间查找过期的key
  2. 惰性删除:访问key的时候检查是否过期

    redis 内存淘汰策略

  3. lru(Least Recently Used):最近最少使用数据淘汰(redis不是使用队列而是使用用时钟生成一个近似顺序)
  4. lfu(Least frequently used):最少使用数据淘汰(时钟末尾改成计数器) 参考

聚簇索引和非聚簇索引的区别

innodb 数据是一个b+数,即所有的枝干是主键索引,所有的叶子是数据,叶子和叶子之间首尾连接。这种索引和数据放在一起的结构叫聚簇索引。非主键索引放在另一个文件,枝干是索引,叶子是主键索引。这种索引是一个单独文件的结构,叫非聚簇索引。

mysql有哪些存储引擎

  1. InnoDB
    灾难恢复性好
    支持事务
    支持行级锁
    支持外键关联
    支持热备份
    对于InnoDB引擎中的表,其数据的物理组织形式是簇表(Cluster Table),主键索引和数据是在一起的,数据按主键的顺序物理分布
    实现了缓冲管理,不仅能缓冲索引也能缓冲数据,并且会自动创建散列索引以加快数据的获取

  2. MyISAM
    不支持事务
    使用表级别锁
    主机宕机后表容易损坏,灾难恢复性不佳
    数据紧凑存储,因此可以获得更小的索引和更快的全表扫描性能

  3. MEMORY(HEAP)
    全内存表,不支持事务和外键

  4. ARCHIVE 只支持insert 和 select
    适合归档历史数据,没有索引,查询比较慢

  5. Cluster/NDB
    官方集群方案专用

  6. CSV

  7. merge/mrg_myisam 在多个相同的 myisam 表上加一层代理,可以用作水平分表 参考

  8. PERFORMANCE_SCHEMA
    该引擎主要用于收集数据库服务器性能参数。这种引擎提供以下功能:提供进程等待的详细信息,包括锁、互斥变量、文件信息;保存历史的事件汇总信息,为提供MySQL服务器性能做出详细的判断;对于新增和删除监控事件点都非常容易,并可以随意改变mysql服务器的监控周期,例如(CYCLE、MICROSECOND)。

参考1
参考2

mysql的4种隔离级别

  1. 读未提交(一个事务可以读另一个事务未提交的内容)
  2. 读已提交(一个事务可以读另一个事务已提交的内容)
  3. 可重读(一个事务不可以读到另一个事务已提交的内容)
  4. 串行化(一次只执行一个事务)

参考

安全

常见攻击防御

  1. sql注入 原理:
    用户提交sql语句,比如 ‘;update user’,那么后台的sql语句会变成select user ‘’;update user ‘’ 防御:
    php使用pdo

  2. xss攻击 原理:
    用户上传js脚本,比如商品详情里上传 防御:
    php使用htmlspecialchars()转换字符

  3. csrf攻击 原理:
    黑客模仿(引导)用户身份发出跨站请求 防御:
    每次请求由服务端先给出token,请求必须验证token

https://segmentfault.com/a/1190000018004657

综合

有一个活动预计1000万用户参与,总计10小时,问怎么部署软硬件

  1. 假设是一个力度大的活动,80%流量落在前10分钟,即1.4万qps。然后根据压测数据申请服务器,注意预留30%性能
  2. 如果不是秒杀场景,可以用令牌桶算法限流。秒杀场景由于是先到先得,可以用消息队列缓存
  3. 有资格参加活动的用户和活动奖品可以预先保存在缓存或消息队列里,数据库只保存最终结果
  4. 可以用一致性哈希算法对用户token进行计算,那么特定用户只会访问特定业务服务器,用户数据和页面固定数据可以缓存在各台业务服务器上,避免单key压力
  5. 缓存和数据库采用集群缓解压力

nginx last 和 break 有什么区别

两者都是停止后续匹配,last 会重新发起请求,而 break 不会

break 通常用于判断如果真实存在的文件,则用break语句停止rewrite检查

1
2
3
if (-f $request_filename) {
break;
}

数据按 id 哈希分表后,怎么按 username 查询

  1. 另外建一张表,存储 username -> id 作为索引
  2. username 基因融入 id 参考

反问

面试最后会问你有什么想问的,这个时候把之前没有答上来的再问回去。这样不一定能面上,但至少能知道答案,避免回去自己在网上查。

其他可以问一下项目组具体是做什么项目,技术栈是什么。