列举一些 PHP 中的设计模式?
单例模式:保证在整个应用程序的生命周期中,单例类的实例只存在一个
工厂模式:定义一个创建对象的接口,让子类去实例化具体类。
观察者模式 发布/订阅模式:当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
适配器模式:将一个类的接口转换成客户希望的接口,使得原本不兼容的接口可以兼容
依赖注入模式:是ioc的一种实现方式。用来减少程序中的耦合
简述一下 PHP 垃圾回收机制(GC)
以引用计数机制为基础,同时使用根缓存区机制,当发现有存在循环引用的zval时,就会把其投入到根缓冲区,当根缓冲区达到配置文件中的指定数量后,就会进行垃圾回收,以此解决循环引用导致的内存泄露问题
如果引用计数减少到零,所在变量容器将被清除(free),不属于垃圾;
如果一个zval的引用计数减少后还大于0,那么它会进入垃圾周期。其次,在一个垃圾周期中,通过检查引用计数是否减1,并且检查哪些变量容器的引用次数是零,来发现哪部分是垃圾。
zset底层怎么实现
zset的编码有ziplist和skiplist两种。 底层分别使用**ziplist(压缩链表)和skiplist(跳表)**实现。
其实有序集合单独使用字典或跳跃表其中一种数据结构都可以实现,假如我们单独使用 字典,虽然能以 O(1) 的时间复杂度查找成员的分值,但是因为字典是以无序的方式来保存集合元素,所以每次进行范围操作的时候都要进行排序;假如我们单独使用跳跃表来实现,虽然能执行范围操作,但是查找操作有 O(1)的复杂度变为了O(logN)。因此Redis使用了两种数据结构来共同实现有序集合。
什么时候使用ziplist什么时候使用skiplist?
当zset满足以下两个条件的时候,使用ziplist:
保存的元素少于128个
保存的所有元素大小都小于64字节
不满足这两个条件则使用skiplist。
PHP的array是真正的数组吗?
在PHP中, 数组是用一种HASH结构(HashTable)来实现的, 通过key值读取,使得可以在O(1)的时间复杂度下实现数组的增删, 并同时支持线性遍历和随机访问.
HTTP中GET和POST的区别
GET在浏览器回退时是无害的,而POST会再次提交请求。
GET产生的URL地址可以被Bookmark,而POST不可以。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只能进行url编码,而POST支持多种编码方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST没有。
对参数的数据类型,GET只接受ASCIl字符,而POST没有限制。
如何解决 PHP 内存溢出问题
1.增大 PHP 脚本的内存分配
2.变量引用之后及时销毁
3.将数据分批处理
php类的静态调用和实例化调用各自的利弊
静态方法可以直接调用,比实例化效率高,但不能自动销毁
列出一些防范SQL注入、XSS攻击、CSRF攻击的方法
转义关键字符,使用PDO预处理方式
过滤输入,使用htmlspecialchars过滤转义
使用token验证 使用验证码
****秒杀
前端:
静态化:将活动页面上所有可以静态显示的元素全部静态化,尽量减少动态元素。
限流:针对某个ip,限制单位之间内的请求数量
禁止重复提交:提交之后按钮禁用
后台:
限制uid访问频率
把请求写到消息队列中,在用数据库订阅消息减库存,再返回给用户端
应对读多写少的业务可以用缓存来分担数据库压力
redis:将所有DB操作放到队列中排队,使用串行处理。
isset() 和 empty() 区别
isset检测变量是否存在,可以传多个值
empty检测变量是否为空
冒泡排序
function mysort($arr)
{
for ($i = 0; $i < count($arr); $i++) {
for ($j = 0; $j < count($arr) - 1 - $i; $j++) {
if ($arr[$j] > $arr[$j + 1]) {
$tmp = $arr[$j];
$arr[$j] = $arr[$j + 1];
$arr[$j + 1] = $tmp;
}
}
}
return $arr;
}
$arr = array(3, 2, 5, 1);
print_r(mysort($arr));
快速排序
$a = array(2, 13, 42, 34, 56, 23, 67, 365, 87665, 54, 68, 3);
function quick_sort($a)
{
// 判断是否需要运行,因下面已拿出一个中间值,这里<=1
if (count($a) <= 1) {
return $a;
}
$middle = $a[0]; // 中间值
$left = []; // 接收小于中间值
$right = [];// 接收大于中间值
// 循环比较
for ($i = 1; $i < count($a); $i++) {
if ($middle < $a[$i]) {
// 大于中间值
$right[] = $a[$i];
} else {
// 小于中间值
$left[] = $a[$i];
}
}
// 递归排序划分好的2边
$left = quick_sort($left);
$right = quick_sort($right);
// 合并排序后的数据,别忘了合并中间值
return array_merge($left, [$middle], $right);
}
print_r(quick_sort($a));
遍历文件夹中所有的文件
<?php
function bl($file="./4927525/.github"){
$temp = scandir($file);
foreach ($temp as $v){
$a = $file . '/' . $v;
if(is_dir($a)){
if($v == '.' | $v == '..'){
continue;
}
echo $a . '<br>';
bl($a);
}else{
echo $a . '<br>';
}
}
}
bl();
请说明 PHP 中传值与传引用的区别,什么时候传值什么时候传引用?
按值传递:函数范围内对值的任何改变在函数外部都会被忽略
按引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改
优缺点:按值传递时,php必须复制值。特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作。按引用传递则不需要复制值,对于性能提高很有好处。(优缺点会考到)
Docker
docker images #查看所有的本地的主机上的镜像
docker search 搜索镜像
docker pull 下载镜像
docker rmi 删除镜像
docker ps 命令列出当前正在运行的容器
exit # 直接容器退出
docker rm 容器ID # 删除指定容器 不能删除正在运行的容器 -f 可以强行删除
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -a -q | xargs docker rm # 删除所有容器
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id
数组和链表的区别
数组:随机访问性强,查找速度快。但是插入和删除效率低,大小固定不能动态扩展
链表:插入删除快,不会浪费内存,大小不固定。不能随即查找。查找效率低
实现session共享
使用redis/mem/mysql作为session存储可以实现多台服务器同一个session_id访问到相同的session内容
php单引号和双引号的区别?
双引号解释变量,单引号不解释变量
双引号转义特殊字符(/r/n之类的),单引号不解释转义字符。
单引号被系统默认是普通字符串类型,会直接编译
自动加载的原理
自动加载的原理,就是在我们new一个class的时候,PHP系统如果找不到你这个类,就会去自动调用本文件中的__autoload($class_name)方法,我们new的这个class_name 就成为这个方法的参数。所以我们就可以在这个方法中根据我们需要new class_name的各种判断和划分就去require对应的路径类文件,从而实现自动加载。
谈谈对消息队列的理解
优点:
程序解耦:两个程序在交互时,不会因为一方中断而导致服务停止
异步处理:可以同时处理多个请求,缩短响应时长
流量削峰:可以适用在商品秒杀,在客户端请求量很大的时候,有效的进行流量削峰
缺点:
消息可用性降低
系统复杂度提高
数据可能不一致
PHP 如何实现多继承
接口多继承
trait
include和require的区别是什么?
include在引入不存在文件时会产生一个警告但会继续运行
require会出现一个致命性错误,并不会运行
长连接、短连接的区别和使用
长连接:client与server建立连接,连接后不断开。且一直存在。
短连接:client与server在通讯时才建立连接。完成后久会断开。
长连接常用于socket通信,短链接常用于web http服务
swoole 为什么这么快 ?和go有什么区别?
常驻内存:避免重复加载带来的性能损耗,提升海量性能
协程异步:提高对 I/O 密集型场景并发处理能力(如:微信开发、支付、登录等)
区别:
swoole使用多线程eventloop处理IO事件,多进程执行用户层php代码
go使用单线程eventloop处理IO事件,多线程实现协程调度,执行用户层代码
协程适用的场景?
高并发服务,如秒杀系统、高性能API接口、RPC服务器,使用协程模式,服务的容错率会大大增加,某些接口出现故障时,不会导致整个服务崩溃。
爬虫,可实现非常巨大的并发能力,即使是非常慢速的网络环境,也可以高效地利用带宽。
即时通信服务,如IM聊天、游戏服务器、物联网、消息服务器等等,可以确保消息通信完全无阻塞,每个消息包均可即时地被处理。
什么是心跳机制?
心跳就是业务层来提供一个连接判断是否存活
客户端定时发送一个心跳包,告诉服务器,服务器定时检测所有客户端。看最后一个心跳包的时间长短。如果过长则主动关闭这个连接。
服务器定时询问所有的客户端。如果没有反馈则关闭连接。
两种心跳方案有什么区别?
第一种,对服务和网络压力小,但需要客户但配合。
第二种对服务器和网络压力大。
传输层主要有哪些协议?
主要有 TCP 和 UDP 协议。他们的区别是 TCP 是需要连接的 会经过三次握手,而且可以保证消息的可靠性。UDP 是不需要连接的,不保证消息的可靠性。
假设现在有多个入口可以同时使用一个账户操作,这个账户只有十块钱,有哪些方法可以使得不超扣消费?
使用悲观锁
redis:lua脚本
队列
PHP的运行模式
cgi:
允许web服务器通过特定的协议与应用程序通信
原理:用户请求 服务器接受 fork子进程调用程序 程序返回内容 服务器接受内容 返回给用户
每次用户请求都要fork进程调用程序,然后销毁。性能较低
fastcgi:
像是一个常驻型cgi,可以一直处理请求不结束进程
原理:fast-cgi初始化 预先fork n个进程 用户请求 服务器接受请求 交给fast-cgi进程管理器 fast-cgi进程管理区接受,给一个空闲的fast-cgi进程处理 处理完成,fast-cgi进程变成空闲状态等待下次请求 服务器接受内容 返回给用户
module模式:
apache+php运行时,默认使用module模式。他把php作为apache的模块随apache一起启动,接收到用户请求时直接调用mod_php模块进行处理并返回给apache
php-cli模式:
属于命令行模式,php 文件名.php直接运行代码
没有超时时间
STDIN/STDOUT标准输入/输出
直接打印到控制台中
php-fpm原理
原理:php-fpm启动 生成n个fast-cgi协议处理器 监听一个端口等待任务 用户请求 服务器接收请求 转发给php-fpm php-fpm交给一个空闲进程处理 进程处理完成 php-fpm返回给服务器 服务器接收数据 返回给用户
OSI网络协议的七个层级
应用层:为用户提供常用的应用程序,每个网络应用对应着不同的协议。例如文件运输访问和管理,电子邮件等。HTTP SMTP
表示层:主要负责数据格式的转换,确保一个系统的应用层发送的消息可以被另一个系统的应用层读取;数据加密
会话层:负责网络中两节点的建立,在数据传输中维护计算机网络中两台计算机之间的通信连接,并决定何时终止通信(建立或解除与其他节点的联系)
传输层:实现两个用户进程间端到端的可靠通信,处理数据包的错误等传输问题 TCP UDP
网络层:逻辑地址寻址,实现不同网络之间的路径选择 IPv4 v6 ARP
数据链路层:建立逻辑连接、进行硬件地址寻址
物理层: 建立,维护,断开物理连接
WebSocket原理
浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。在此WebSocket 协议中,为我们实现即时服务带来了两大好处:
Header: 互相沟通的Header是很小的-大概只有 2 Bytes
Server Push: 服务器的推送,服务器不再被动的接收到浏览器的请求之后才返回数据,而是在有新数据时就主动推送给浏览器。
http协议中,服务器如何区分不同用户?
服务端可以通过User-Agent获得用户的浏览器信息,可以通过cookie获取自定义的信息
用户A第一次进入,没有附带cookie
服务端记录这个用户,响应头增加一个set_cookie:id=1的cookie
浏览器获得响应头,解析到set_cookie动作,把id=1存进cookie
第二次请求服务端,带上id=1的cookie,服务端就可以知道:这次请求时用户A请求的
同理,用户B第一次进入,服务端响应set_cookie:id=2
可以看出,只要用户端每次请求,跟服务端约定好一个参数作为用户标识,服务端就可以通过这个标识区分不同的用户了
token原理?
用户A第一次进入,通过验证机制(账号密码登陆)请求服务端token
服务端验证成功,给用户发送一个token(针对用户)
服务端根据token,在服务端存储对应的数据(文件,mysql,redis等)
用户A端获取到token,存储到用户端本地
用户A请求某接口,带上token
服务端通过token,验证用户有效性,返回数据
LINUX相关
微服务
单点登录实现原理
单点登录是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统的保护资源,若用户在某个应用系统中进行注销登录,所有的应用系统都不能再直接访问保护资源
最后这一份工作中有没有什么比较复杂的实现不了,怎么解决的?
高并发解决
扩容
增加服务器,搭建集群
减少并发/分流/限流
使用异步操作减少并发。
一些数据处理在夜间运行
通过nginx反代,实现负载均衡
数据库分表分库
缓存
浏览器缓存,CDN,ORM缓存,REDIS数据缓存
同时要解决数据一致性问题,缓存雪崩,穿透 击穿
微服务
将并发高得模块拆出来。模块如果挂掉不影响其他模块
程序代码优化
常驻内存模式开发下,尽量减少使用new,使用单例模式,还有连接池的使用
拖库 洗库 撞库
拖库:
通过对目标网站扫描,查找漏洞,进行sql注入,文件上传在服务器建立后门(webshell)获取root权限,下载数据库
避免:
对数据库密码进行加密,设置黑白名单。
用户要单独设置密码,定义修改密码。
洗库:
获取用户数据后,将数据变现。
撞库:
将数据在其他网站上进行登录。
避免:
一段时间内密码超过次数封ip,加入验证码。
redis做延迟队列
zset, 要发送的内容id作为key, score是发送时间.
因为时间是有序的. 第一个没到发送时间,后面的肯定也没到
每次检测第一个., 如果没到发送时间, 休眠0.5秒. 否则就开始根据ID取出内容发送.
这样发送的内容都不在内存中
这是分发器的实现,分发器将到时间了要发送的推到队列,由发送器去即时发送;
负载均衡
HTTP重定向:
请求到负载均衡服务器
服务器返回304,重定向到实际负责处理的服务器ip给浏览器 Ip在响应头的location中
浏览器请求该服务器
服务器响应数据到浏览器
缺点:
请求经过两次服务器,增加了响应时间
暴露了实际的服务器ip,安全性低
DNS负载均衡:
用户请求域名,请求到DNS服务器
DNS解析程ip返回给客户端,并不返回给浏览器进行重定向
客户端拿到ip请求服务器
服务器返回响应数据
可以不用每次都请求负载的ip,可以把返回到客户端的ip缓存起来,重复值使用,提高性能
dns不会暴露真实ip
反向代理负载均衡:
代理服务器来接受请求,然后将请求转发给内网服务器,再将获得的内容返回给客户端。
什么是分布式系统
就是能把系统进行拆分并部署到多台服务器上的系统
为何需要分布式
单台服务器已经无法承受访问压力 大数据处理 高并发访问 高可用性,自动容错 并行、高性能应用
防止sql注入
进行sql预编译
过滤转义参数
确认每种数据的类型
确认数据长度
设置数据库权限
sql异常信息用自定义代码响应
什么是Http协议无状态协议?怎么解决Http协议无状态协议?
无状态协议对于事务处理没有记忆能力。可以通过cookie session保存
Http协议有什么组成?
请求报文包含三部分:
请求行:包含请求方法、URI、HTTP版本信息
请求首部字段
请求内容实体
响应报文包含三部分:
状态行:包含HTTP版本、状态码、状态码的原因短语
响应首部字段
响应内容实体
跨域问题
设置响应头允许跨域 Access-Control-Allow-Origin
nginx做反代,请求不同项目,用路径方式区分,请求到nginx做拦截,转发给不同ip和端口。
创建触发器
触发器名建议为trigger_xxx,这样便于区分,触发器名不能重复。
before|after 代表触发器语句执行时间,如果是before,就是在insert delete update操作之前执行触发器语句;after就是之后。
事件就是insert delete update操作中的一个。
for each row 是代表任何记录执行对应操作都会触发器。
触发器语句就是触发器触发时要执行的语句。
比如:下面是一个当插入新用户时,在用户创建时间表中插入一条新数据,是当前时间。
create trigger trigger_addUserTime before insert on user_info for each row insert into usercreatetime(create_time) values(now());
提权
系统漏洞提权 linux windows
windows:漏洞编号 exp
linux:exp
数据库提权
通过执行数据库语句、数据库函数等方式提升服务器用户的权限。
系统配置错误提权
权限继承类提权
第三方软件地权
WebServer漏洞提权
CSRF攻击原理
登录受信任的网站A,在本地生成cookie
在不登出A的情况下,访问危险网站B
这时B要求访问A,发送一个request,并带上cookie
因为A不知道是用户还是b发出来的,就会处理请求
页面局部静态化
局部页面静态化就是指在纯html静态化文件中有部分的数据是动态获取的;
它所用的技术就是ajax技术;
它的原理就是在生成纯静态html文件的模版文件中,使用ajax技术来动态的获取并更新需要动态的部分;
这样,在生成的纯静态的html文件中就包括了动态数据的部分,而这个文件就是局部静态化的html文件;
无限极分类原理
每一个分裂都有一个父id
当为顶级分类时,父id为0
可以通过父id找到所有父类,层级为几
持久化连接和非持久化连接的区别。
持久连接:使用同一个TCP连接可以发送和接收多个http请求/应答。
非持久连接:一个TCP连接只能发送和接收一个http请求/应答。
mysql和mysqli redis的connect 和pconnect
脚本结束后连接就被释放
脚本结束后连接不被释放
超时时间是由nginx决定还是fpm决定
如果出现 502 bad Gateway的原因一般是 php 程序执行超时 修改php-fpm.conf中的请求时间
如果出现504GateWay TimeOut,是nginx转发给fastcgi的请求超时。
select、poll、epoll的原理与区别
select:
同步多路IO复用
fd连接数限制
用轮询方式对socket扫描,效率低
poll:
同步多路IO复用
用链表的方式,使其没有连接数限制
epoll:
select和poll是主动轮询机制,epoll是被动触发的,
epoll会把哪个流发生了怎样的I/O事件通知我们
连接双全工http
http1.1以下为短链接:TCP连接发送信息等待接受信息之后断开
http1.1:半双工
http2.0是全双工
二分算法实现
MQ的两种工作模式
点对点:不可重复消费
发布/订阅:可以重复消费
异步JOB队列JOB如果有依赖关系,要怎么处理
job可能有3个步骤, 执行第一个, 符合条件,投递第二个job
执行第二个job, 符合条件, 投递第三个job
以此类推
123步,是由不同进程/线程完成的
1.数据库设计为什么进行分表,分库
先按业务垂直分库,再按业务垂直分表,再按字段水平分表
随着时间和业务的发展,库中的表会越来越多,表的数据量也会越来越大。增删改查的开销也会越来越大。
2.索引是什么?
索引是一种基于表的数据结构,它可以加快数据的检索。类似书的目录
3.Mysql实现底层btree机制
4.索引的优点和缺点
加快了数据的检索速度
创建唯一索引,可保证数据库表中每行数据的唯一性
加速表与表的连接
使用分组和排序子句进行数据检索时,可以减少查询时间
创建和维护索引耗费时间
占物理空间
增删改的时候索引也要动态的维护
5.说下数据库,你觉得mysql最重要的是什么
MySQL 是一种开源的关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性
6.什么是事务?
指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
7.事务的隔离级别
读未提交
这种事务隔离级别下,select语句不加锁,此时可能不一致的数据,读脏。是并发最高,一致性最差的隔离级别
读提交 RC
可能会出现幻读
可重复读 RR
无论读几次都不会读到重复的数据
串行化
如果有未提交的事务正在修改某些行,所有读取这些行的select就会被堵塞住,一致性最好的,但并发性最差的隔离级别。
8.事务运行的三种模式
自动提交事务
每条单独的语句都是一个事务,每个语句都隐含一个commit
显式事务
以begin transaction 开始,以commit 或 rollback 结束
隐性事务
在前一个事务完成时,新事务隐式启动,但每个事务仍以commit或rollback显示结束 。
9.mysiam和innodb的区别
I 支持事务,M不支持事物
I 支持外键,M不支持外键
select count(*) from table 时 M快,因为他有一个变量存着表的总行数,I需要全表扫描
I 支持表 行锁,M只支持表锁
10.输入URL访问网页的过程/web工作原理
用户在浏览器输入网址
dns服务器解析/或者本机hosts,路由器hosts对比 获得ip
浏览器访问默认端口80,则访问的tcp地址为 ip:80。
tcp协议3次握手,建立连接
发送一个http request请求头
服务器获得http request请求头,表明该次访问为http访问,解析http请求头,获得请求类型,请求格式,以及请求数据(cookie,get,post数据)
服务器发送response响应数据,主动断开
浏览器接收response响应数据,解析响应文本类型,解析数据,断开连接
11.session和cookie的区别是什么
session存在服务器端,cookie存在浏览器端,session比较安全
禁用cookie后,session也会失效,但是可以通过url中传递session_id来实现。
session可以放在文件,数据库,内存中
12.session是存储在什么地方,以什么形式存储的
session是存在服务器的内存中 通过sessionId区分是哪个会话,以键值对的形式存储
13.说一下多进程和多线程的区别
进程是资源分配的最小单位,线程是CPU调度的最小单位
内存/cpu:多进程占用内存多,切换复杂,cpu利用率低。多线程占用内存少,切换简单,CPU利用率高
创建/销毁:多进程创建销毁速度慢 ,多线程速度快
编程调试:进程编程/调试简单,线程复杂
可靠性:进程间不会相影响。一个线程挂掉将导致整个进程挂掉。
协程与线程区别
Swoole的协程在底层实现上是单线程的,因此同一时间只有一个协程在工作,协程的执行是串行的。这与线程不同,多个线程会被操作系统调度到多个CPU并行执行。
一个协程正在运行时,其他协程会停止工作。当前协程执行阻塞IO操作时会挂起,底层调度器会进入事件循环。当有IO完成事件时,底层调度器恢复事件对应的协程的执行。
对CPU多核的利用,仍然依赖于Swoole引擎的多进程机制。
协程与进程
协程只是一串运行在进程中的任务代码,只是这些任务代码可以交叉运行
协程并不是多任务并行,属于多任务串行,每个进程在一个时间只执行了一个任务
14.web开发方面会遇到哪些缓存,分别如何优化
浏览器缓存
在任何现代浏览器上 (如 IE, FireFox, Chrome) 折腾清除隐私数据的对话框,你很可能会注意到 “缓存” 这个设置项。
代理服务器缓存
Web 代理服务器使用同样的缓存原理,只是规模更大。代理以同样的方式服务千万用户,大公司和 ISP 经常在他们的防火墙或者单独的设备(也被称为中介 (intermediaries))上架设代理缓存。
网关缓存
也被称为 “反向代理缓存” 或 “替代缓存”。网关缓存同样是起中介作用的,不过不是网络管理员部署的,而多半是网站管理员(公司专门的运维工程师、或 UED 或程序组某人 Add)部署,这样更容易扩展与维护。
15.TCP/IP五层模型?都有什么协议?详细功能?
应用层(应用层,表示层,会话层) 为用户的应用进程提供网络通信服务
协议:域名系统DNS协议、HTTP协议、SMTP协议等
传输层 负责两台主机之间的数据传输,使得数据能从发送端传输到接收端
协议:TCP协议和UDP协议
网络层 负责地址管理和路由选择,在复杂的网络环境中确定一个合适的路径
协议:IP协议
数据链路层 负责设备之前的数据帧的传送和识别,将网络层交下来的数据报封装成帧,在同一个数据链路节点的两个设备之间传输
协议:MTU协议和ARP协议
物理层 实现相邻计算机节点之间比特流的透明传输,尽可能屏蔽掉具体传输介质的差异
应用层:为用户提供常用的应用程序,每个网络应用对应着不同的协议。例如文件运输访问和管理,电子邮件等。HTTP SMTP
表示层:主要负责数据格式的转换,确保一个系统的应用层发送的消息可以被另一个系统的应用层读取;数据加密
会话层:负责网络中两节点的建立,在数据传输中维护计算机网络中两台计算机之间的通信连接,并决定何时终止通信(建立或解除与其他接点的联系)
传输层:实现两个用户进程间端到端的可靠通信,处理数据包的错误等传输问题 TCP UDP
网络层:逻辑地址寻址,实现不同网络之间的路径选择 IPv4 v6 ARP
数据链路层:建立逻辑连接、进行硬件地址寻址
物理层: 建立,维护,断开物理连接。
16.进程和线程的区别
调度:进程作为拥有资源的基本单位,线程作为调度和分配的基本单位
并发性:进程之间可以并发执行,同一进程的多个线程之间也可以并发执行
拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源。
系统开销:进程创建/销毁时开销大于线程。
17. 进程之间通信IPC
进程间的通信叫 IPC (InterProcess Communication),指在不同进程之间传播或交换信息。
IPC 的方式 有 管道(无名管道和命名管道)、消息队列、信号量、共享存储、Socket(支持不同主机上的两个进程IPC)
管道
在内核中申请一块固定大小的缓冲区,程序有读写权利,它是一种特殊的文件,不属于任何文件系统,只存在于内存中。面向字节流、自带同步互斥机制、半双工,单向通信,两个管道实现双向通信。
无名管道:一般使用fork函数实现父子进程通信。
命名管道:用于没有血缘关系的进程也可以进程间通信。
消息队列
在内核中创建一队列,队列中的每个元素是一个数据报,不同进程可以通过句柄访问这个队列。消息队列独立与发送和接受进程,可以通过顺序和消息类型读取。消息队列可以实现双向通信。
信号量
在内核中创建一个信号量合集(数组),信号量(数组的元素)都是1,使用P操作-1,使用V操作+1,通过对临界资源进行保护实现多进程的同步。
共享内存
将同一块物理内存一块映射到不同的进程的虚拟地址空间中,实现不同进程对同一资源共享。是目前最快的IPC形式,直接从内存中直接读取。由于共享资源是临界资源,操作室需要保证原子性,可使用信号量或互斥锁。
socket
socket是应用层与TCP/IP协议通信的中间软件抽象层,是一组接口,复杂的TCP/IP协议隐藏在Socket接口后面。socket是一种“open-read/write-close”的模式实现,服务器和客户端鸽子维护一个“文件”,建立连接打开后可以向自己文件写入内容共对方读取或者读取对方的内容,通讯结束时关闭文件。是一种可以网间通信的方式。
18. 配置Nginx实现负载均衡
轮询:按请求时间逐一分配到不同的服务器,如果有服务器宕机,能够自动剔除
权重:通过配置权重,让性能好的服务器访问几率大
ip_hash:使同一ip的访客固定访问一台服务器
通过在upstream节点中添加ip并指定参数来实现
19. http和https区别,常用方法都有哪些,加密过程
https 的加密是对称还是非对称(这题明显就是挖好坑等我跳的, 正确答案是既使用了对称(加密消息体)又使用了非对称(加密对称 key))
区别:
https协议需要到CA申请证书
http信息是明文传输,https有安全性的ssl/tls加密传输协议
连接方式不同,端口也不同。
http的连接时无状态的,https是由ssl/tls+http构建的可进行加密传输、身份认证的网络的协议
加密:
对称加密:靠一个密钥加密和解密数据。由客户端发送密钥给服务器,客户端将加密后的数据发送给服务器,服务器用相同的密钥解密数据。
非对称加密:服务器端把公钥传给客户端,客户端拿着公钥对数据进行加密,然后客户端发送加密过的数据到服务器,服务器将加密后的数据用私钥解密
20. HTTP 1.x和HTTP 2.0的区别
新的二进制格式:1.x的解析是基于文本的,而2.0是采用二进制格式解析的
多路复用:每一个request都是用作连接的,一个request对应一个id,接收方可以根据request的id将request归属到不同的服务器请求中
header压缩:1.x不支持header数据的压缩,2.0进行了压缩,使数据体积变小,传输更快
服务器推送:2.0引入了server push,服务端可以推送资源给浏览器。
21.对称加密和非对称加密相关
对称加密:采用单钥加密方法,同一个密钥可以同时作为信息的加密和解密。 算法公开,计算量小,速度快。双方都需要保存这个密钥
非对称加密:两个密钥进行加密解密,服务器存着公钥和私钥,发送给浏览器端公钥进行加密传输信息。 速度慢但是能保证安全
22. TCP和UDP区别、应用场景
区别:
连接性:TCP建立连接需要三次握手,断开连接需要四次握手。 UDP不需要建立连接。
他们的区别是 TCP 是需要连接的 会经过三次握手,而且可以保证消息的可靠性。UDP 是不需要连接的,不保证消息的可靠性
可靠性:TCP利用握手,ACK应答和重传机制,UDP没有
有序性:TCP利用seq序列号对包进行排序,UDP没有
应用场景:
TCP:效率要求相对低但对准确性要求高的场景,例如文件传输,远程登陆,接收重要信息
UDP:效率要求较高但准确性相对低的场景,实时通讯,广播
23. 三次握手过程?四次挥手过程
三次握手:
1. 首先服务器监听某个端口,客户端发起请求 携带 syn 数据包 (第一次) 2. 服务端接收到这个数据包,返回 syn/ack 的数据包给客户端 (第二次) 3. 最后客户端再次发送一个 ack 的数据包(第三次)。
四次挥手:
客户端发送一个FIN(关闭连接),用来关闭客户端到服务器的数据传送,此时客户端进入FIN_WAIT_1状态
服务器收到FIN后,发送一个ACK给客户端,确认序号为收到需要+1(与SYN相同,一个FIN占用一个序号),此时服务器进入CLOSE_WAIT状态
服务器发送一个FIN,用来关闭服务器到客户端的数据传送,服务器进入LAST_ACK状态
客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个ACK给服务器,确认序号为收到的序号+1,服务器进入CLOSED状态。
23. Redis相关
24. 查询一个日志文件中访问次数最多前10个IP?
按照IP进行将记录排序。
按照IP去重,并且显示重复次数
按照次数升序排列
显示前10行
cat log.txt|awk -F" " ‘{print &1}’ |sort|uniq -c|sort -nrt " “|awk -F” " ‘print &2’ |head -10
25. ————zval
26. Opcache是什么
Opcache是一种通过将解析的PHP脚本预编译的字节码存放在共享内存中来避免每次加载和解析PHP脚本的开销,解析器可以直接从共享内存读取已经缓存的字节码,从而大大提高PHP的执行效率。
27.请求PHP脚本时的过程
PHP 初始化执行环节,启动 Zend 引擎,加载注册的扩展模块。
初始化后读取 PHP 脚本文件,Zend 引擎对 PHP 文件进行词法分析,语法分析,生成语法树。
Zend 引擎编译语法树,生成 Opcode。
Zend 引擎执行 Opcode,返回执行结果。
28. CGI FastCGI fpm module 运行模式
cgi:
允许web服务器通过特定的协议与应用程序通信
原理:用户请求 服务器接受 fork子进程调用程序 程序返回内容 服务器接受内容 返回给用户
每次用户请求都要fork进程调用程序,然后销毁。性能较低。
fastcgi:
像是一个常驻型cgi,可以一直处理请求不结束进程
原理:fast-cgi初始化 预先fork n个进程 用户请求 服务器接受请求 交给fast-cgi进程管理器 fast-cgi进程管理区接受,给一个空闲的fast-cgi进程处理 处理完成,fast-cgi进程变成空闲状态等待下次请求 服务器接受内容 返回给用户
module模式:
apache+php运行时,默认使用module模式。他把php作为apache的模块随apache一起启动,接收到用户请求时直接调用mod_php模块进行处理并返回给apache
php-cli模式:
属于命令行模式,php 文件名.php直接运行代码
没有超时时间
STDIN/STDOUT标准输入/输出
直接打印到控制台中
29. PHP设计模式
单例模式:保证在整个应用程序的生命周期中,单例类的实例只存在一个
工厂模式:定义一个创建对象的接口,让子类去实例化具体类。
观察者模式 发布/订阅模式:当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
适配器模式:将一个类的接口转换成客户希望的接口,使得原本不兼容的接口可以兼容
依赖注入模式:是ioc的一种实现方式。用来减少程序中的耦合
30.堆和栈的区别
申请方式的不同。栈由系统自动分配,而堆是人为申请开辟;
申请大小的不同。栈获得的空间较小,而堆获得的空间较大;
申请效率的不同。栈由系统自动分配,速度较快,而堆一般速度比较慢;
存储内容的不同。栈在函数调用时,函数调用语句的下一条可执行语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的。而堆一般是在头部用一个字节存放堆的大小,堆中的具体内容是人为安排;
底层不同。栈是连续的空间,而堆是不连续的空间。
31.数据库中主键和唯一索引的区别?
主键为一种约束,唯一索引为一种索引,本质上就不同。
主键在表中只能有一个,唯一索引可以有多个。
主键创建后一定包含唯一性索引,而唯一索引不一定就是主键。
主键不能为null,唯一索引可以为null.
主键可以被其它表引用,唯一索引不能。
主键和索引都是键,主键是逻辑键,索引为物理键,即主键不实际存在。