PHP面试/笔试题杂记 I

每次面试或者说每次看面试题笔试题总能发现一些自己不熟悉,或者说自己平时会忽略的点
所以决定平时常看看笔试题有助于提高自己!

问题无先后,看到什么或者想起什么就查询并且记录下.

MySQL事务是什么 ?

  • 什么是事务 ?
    • 一个事务必须满足四个条件: 原子性,一致性,隔离性,持久性
      • 原子性: 一个事务中的操作要么全部完成,要么全部不完成
      • 一致性: 之物开始前后,数据库的完整性没有破坏
      • 隔离性: 未提交读(RU),提交读(RC),可重复读(RR),串行话(Serializable)
      • 持久性: 事务结束会后对书画家的修改是永久的
    • 事务命令
      • begin 开始事务
      • rollback 回滚事务
      • commit 提交事务
    • MySQl中只有Innodb引擎支持事务

PHP代码解释过程 ?

1
2
3
4
5
<?php

echo "Hello world",
$a = 1 + 1;
echo $a;
  • PHP执行代码有以下四个步骤
    • Scanning(Lexing), 将PHP代码转换为语言片段(Tokens)
    • Parsing, 将Tokens转换成简单而有意义的表达式
    • Compilation, 将表达式编译成Opcodes
    • Execution, 顺次执行Opcodes,每次一条,从而实现PHP脚本的功能

如何共享Session ?

  • 为什么要共享session ?

假设某个网站是由多台服务器提供服务,nginx采用轮询机制做负载均衡,那么同一个IP访问该网站时,请求就可能会被分配到不同的服务器上,如果session没有实现共享,就回出现重复登陆授权的情况

  • 共享session的几种方式
    • 基于NFS的session共享: NFS(Net FileSystem,网络文件系统),即将session存储目录挂载到所有的服务器上,实现session的读写
    • 基于Cookie的session共享
    • 基于数据库的session共享
    • 基于Memcache/Redis的session共享

git分支管理策略

  • 答: master做主分支,dev做开发分支,bug_fix做bug分支
  • 问: 有个临时bug需要改,而我们在dev上已经开发了很多内容了,怎么办?
  • 答: bug_fix分支拉master,处理完再合并回master,问题是会和dev的相同模块冲突
  • 解决: 使用git rebase变基实现
1
git rebase --onto master server client

以上命令的意思是:“取出 client 分支,找出处于 client 分支和 server 分支的共同祖先之后的修改,然后把它们在 master 分支上重放一遍”

Restful 设计

  • GET (SELECT): 从服务器取出资源(一项或多项)
  • POST (CREATE): 从服务器新建一个资源
  • PUT (UPDATE): 在服务器更新资源 (客户端提供改变后的完整资源, 简单来说更新完整资源)
  • PATCH (UPDATE): 在服务器更新资源 (客户端提供改变的属性, 简单来说更新部分资源)
  • DELETE (DELETE): 从服务器删除资源

  • HEAD: 获取资源的元数据

  • OPTIONS: 获取信息, 关于资源的哪些属性是客户端可以改变的

了解哪些设计模式, 实际用例 ?

  • 工厂模式: 定义一个标准, 用到的类可以按这个标准实现相应功能
  • 单例模式: 防止重复实例化, 减少资源调用
  • 数据映射模式: 数据库ORM应用
  • 装饰器模式: 兼容老数据,多态的应用
    • 怎么兼容老数据?

Ajax跨域请求时,会出现什么问题 ?如何解决 ?

  • Ajax跨域请求的问题 ?
    • 因为浏览器同源策略导致请求跨域错误.
    • 可能出现一下几种问题:
      • No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 404
        • 解决方案: 后端运行options请求
      • No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 405
        • 解决方案: 后端关闭对应的安全配置
      • No 'Access-Control-Allow-Origin' header is present on the requested resource,并且status 200
        • 解决方案: 后端增加对应的头部支持
      • heade contains multiple values '*,*'
        • 解决方案: 建议删除代码中手动添加的, 只用项目配置中的即可;建议删除ISS下的配置,只用项目配置中的即可

ajax跨域,这应该是最全的解决方案了

  • 如何解决?
    • JSONP: 因为 <script> 脚本拥有跨域能力
    • CORS (Cross-Origin-Resource-Sharing, 跨域资源共享)
    • 代理请求: node.js,代理请求

redis异步队列实现细节 ?

  • redis提供了两种方式来做消息队列

    • 生产者消费模式(PUSH/POP机制)
      • 让一个或者多个客户端监听消息队列, 一旦消息到达,消费者马上消费,谁先抢到算谁的,如果队列里没有消息,则消费者继续监听.
    • 发布订阅者模式(PUB/SUB机制)
      • 一个或者多个客户端订阅消息频道,只要发布者发布消息,所有订阅者都能收到消息,订阅者是平等的.
  • 如何实现 ?

以Laravel为例:

  • 使用list,通过lpush入队列,rpop出队列处理任务
  • 使用php artisan queue:work开启后台进程监视队列,并完成任务
  • 通过dispatch()触发任务

redis中zest如何根据两个属性排序,比如id和age

  • Redis中用于实现排序功能的是SORT命令
  • 但是Redis并不擅长排序,可以将操作放到业务或者DB中处理,使Redis仅仅起一个缓存作用.

你对多进程和多线程还有协程的理解 ?

  • 进程多与线程比较

    • 线程是指进程内的一个执行单元,也是进程内的可调度实体, 区别:
      • 地址空间: 多个线程共享进程的地址空间,进程有自己独立的地址空间
      • 资源拥有: 进程是资源分配和拥有的单位,同一个进程内线程共享进程的资源
      • 线程是处理器调度的基本单位,进程不是
      • 二者均可以并发执行
      • 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能够独立执行,必须依存在应用程序中
  • 协程多与线程比较

    • 一个线程可以多个协程,一个进程也可以单独拥有多个协程
    • 线程进程都是同步机制,而协程则是异步
    • 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态.

nginx负载均衡和反向代理 ?

  • 什么是负载均衡 ?

负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。

1
2
3
4
5
6
7
8
9
10
upstream myapp {
server 192.168.20.1:8080; # 应用服务器1
server 192.168.20.2:8080; # 应用服务器2
}
server {
listen 80;
location / {
proxy_pass http://myapp;
}
}
  • 负载均衡算法:

    • Round Robin (轮询): 为第一个请求选择列表中的第一个服务器,然后按顺序向下移动列表直到结尾,然后循环。
    • Least Connections (最小连接): 优先选择连接数最少的服务器,在普遍会话较长的情况下推荐使用。
    • Source: 根据请求源的 IP 的散列(hash)来选择要转发的服务器。这种方式可以一定程度上保证特定用户能连接到相同的服务器。
  • 什么是反向代理 ?

反向代理是代理服务器的一种。服务器根据客户端的请求,从其关系的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理的IP地址,而不知道在代理服务器后面的服务器簇的存在

1
2
3
4
5
6
server {
listen 80;
location / {
proxy_pass http://192.168.20.1:8080; # 应用服务器HTTP地址
}
}
  • php-fpm能代理其他端口吗? 除了默认9000.

    • 什么是php-fpm ?
      • PHP-FPM是PHP的一个FastCGI管理器
        • FastCGI,顾名思义就是更快的CGI程序,用来提高CGI程序性能,它允许在一个进程内处理多个请求,而不是一个请求处理完毕就直接结束进程,性能上有了很大的提高。
    • 所以可以是任何一个没有被占用的端口
  • nginx配置php-fpm的时候走的是什么协议? 还可以走其他协议吗?

    • CGI协议,FastCGI协议

当我们访问一个网站,如www.test.com的时候,处理流程是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  www.test.com
|
|
Nginx
|
|
路由到 www.test.com/index.php
|
|
加载 nginx 的 fast-cgi 模块
|
|
fast-cgi 监听 127.0.0.1:9000 地址
|
|
www.test.com/index.php 请求到达 127.0.0.1:9000
|
|
等待处理...

BTree 和 B+tree ?

  • BTree: B树是为了磁盘或者其他存储设备而设计的一种多叉平衡查找树,相对于二叉树,B树的每个内节点有多个分支,即多叉。
  • B+Tree: B+树是B树的变体,也是一种多路搜索树

三次握手,四次挥手, 为什么是三次握手四次挥手?

  • 三次握手:

    • 第一次握手:A与B建立TCP连接时,首先A向B发送SYN(同步请求)
    • 第二次握手:然后B回复SYN+ACK(同步请求应答)
    • 第三次握手:最后A回复ACK确认
  • 四次挥手:

    • TCP的连接的拆除需要发送四个包,因此称为4次挥手.客户端或服务器均可主动发起挥手动作

长连接和短连接 ?

  • TCP短连接

    • client向server发起连接请求
    • server接到请求,双方建立连接
    • client向server发消息
    • server回应client
    • 一次读写完成,此时双方任何一个都可以发起close操作
      一般都是client先发起close操作,因为一般的server不会回复完client就立即关闭连接
  • TCP长连接

    • client向server发起连接
    • server接到请求后,双方建立连接
    • client向server发送消息
    • server回应client
    • 一次读写完成,连接不关闭
    • 后续读写操作
  • 长/短连接的优缺点

    • 长连接可以省去较多的TCP建立和关闭操作,减少资源浪费,节省时间,对于比较频繁的请求资源的客户端比较适用于长连接
    • 短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段

从浏览器输入域名到展示页面都发送了什么 ?

  • DNS域名解析

先找本地host文件,检查对呀域名ip的关系,有则向ip地址发送请求,没有再去找DNS服务器

  • 建立TCP连接

拿到服务器IP后,向服务器发送请求,三次握手,建立TCP连接

简单理解三次握手:
客户端: 您好,在家不,有你快递
服务端: 在的,送来吧
客户端: 好滴,来了

  • 发送HTTP请求

与服务器建立连接后,就可以向服务器发起请求了,具体请求内容可以再浏览器中查看

  • 服务器处理请求

服务器收到请求后由web服务器(Apache,Nginx)处理请求,web服务器解析用户请求,知道了需要调用那些资源文件,再通过相应的这些资源文件处理用户请求和参数,并调用数据库等,然后将结果通过web服务器返回给浏览器

  • 返回响应结果

在响应结果中都会有一个HTTP状态码,诸如我们熟知的200、404、500等

状态码都是由三位熟知和原因短语组成的,大致分5类:


  • 1XX 信息状态码,接受的请求正在处理
  • 2XX 成功状态码,请求正常处理完毕
  • 3XX 重定向状态码,需要附加操作以完成请求
  • 4XX 客户端错误状态码,服务器也无法处理的请求
  • 5XX 服务器错误状态码,服务器请求处理出错

  • 关闭TCP连接

为了避免服务器与客户端双方资源占用和消耗,当双方没有请求或者响应传递时,任意一方都可以发起关闭请求,与创建TCP连接的三次握手类似,关闭TCP连接需要4次挥手

简单理解四次挥手:
客户端: 哥们,我这边没有数据要传了,咱们关闭连接吧
服务端: 好的,我看看我这边还有数据不
服务端: 兄弟, 我这边也没有数据要传给你了, 咱们可以关闭连接了
客户端: 好勒

  • 浏览器解析HTML
  • 浏览器布局渲染

队列和栈的区别 ?

  • 什么是队列? 什么是栈?

      1. 队列(Queue): 是限定只能在表的一端进行插入和在另外一端删除操作的线性表
      1. 栈(Stack): 是限定只能在表的一端进行插入和删除操作的线性表
  • 队列和栈的规则

      1. 队列: 先进先出
      1. 栈: 先进后出
  • 队列和栈的遍历数据速度

      1. 队列: 基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快
      1. 栈: 只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,而且在遍历数据的同事需要微数据开辟临时空间,保持数据在遍历前的一致性。

GET和POST提交方式的区别 ?

  • GET产生一个TCP数据包;POST产生两个TCP数据包

    • 对于GET请求,浏览器会吧http header和data一并发送出去,服务器响应200 ok(返回数据)
    • 对于POST请求,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器返回200 ok(返回数据)
  • GET在浏览器回滚时是无害的,而POST会再次提交请求

  • GET请求会被浏览器主动cache,而POST不会,除非手动设置
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
  • GET请求只能进行url编码,而POST支持多种编码方式
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息

请列举你熟悉的Linux命令(越多越好)

  • ls ll pwd cd cp mv rm mkdir rmdir
  • touch vim vi head tail diff cat echo
  • useradd userdel chown chmod passwd
  • top iotop vmstat df du
  • find grep xargs wed wc
  • whatis info man which whereis whoami who w
  • hostname uname tar gzip gunzip
  • kill pkill lsof sar free watch netstat route ping
  • wget make ssh sftp scp

如何实现单点登录 ?

  • 什么是单点登录 ?

    • 单点登录(Single Sign On,简称SSO,在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统)
  • 如何实现单点登录 ?

    • 实现session共享

用户权限如何而设计 ?

  • user 用户表
  • role 角色表
  • permission 权限表
  • role-user 用户角色关联表
  • role-permission 角色权限关联表

后续待更…

Powered by Hexo and Hexo-theme-hiker

Copyright © 2017 - 2021 Keep It Simple And Stupid All Rights Reserved.

访客数 : | 访问量 :