1、设计模式
单例、工厂、适配器、策略、观察者、注册 、原型、装饰器
2、高并发
流量:防止盗链、限制恶意请求
前端:页面缓存、限制大文件下载、图片压缩、cdn加速
后端:队列、静态缓存、并发处理
数据库:缓存、优化、负载均衡、分库、读写分离
服务器:nginx 反向代理、lvs 负载均衡,分流主机。加带宽
3、post与get区别
get url链接明文访问、不安全、传输数据受限、搜索数据
post 相对安全、数据不限、提交数据
4、apache和nginx区别
apache 稳定、动态处理优于nginx、占内存大、重写机制好
nginx 并发能力强、占内存小、静态资源处理好、10万并发、配置简单
Nginx相对于Apache的优势:
1.轻量级,采用C进行编写,同样的web服务,会占用更少的内存及资源
2.抗并发,nginx以epoll and kqueue作为开发模型,处理请求是异步非阻塞的,多个连接对应一个进程,
负载能力比apache高很多,
而apache则是同步多进程模型,只能一个连接对应一个进程,当压力过大时,它是会被阻塞型的。
在高并发下nginx能保持低资源低消耗高性能 ,而apache在PHP处理慢或者前端压力很大的情况下,
很容易出现进程数飙升,从而拒绝服务的现象。
3.设计高度模块化,编写模块相对简单
4.配置简洁,正则配置让很多事情变得简单,而且改完配置能使用 -t 测试配置有没有问题,
apache 配置复杂 ,重启的时候发现配置出错了,会很崩溃
5.一般用于处理静态文件,静态处理性能比apache高三倍以上
6.作为负载均衡服务器,支持7层负载均衡
7.本身就是一个反向代理服务器,而且可以作为非常优秀的邮件代理服务器
8.nginx启动特别容易, 并且几乎可以做到 7*24 不间断运行,即使运行数个月也不需要重新启动,
支持热部署,比如:实现不间断服务的情况下进行软件版本的升级与版本的回退
9.社区活跃,各种高性能模块出品迅速
Apache相对于Nginx的优势:
1.apache的rewrite比nginx强大,在rewrite频繁的情况下,用apache
2.apache发展到现在,模块超多,基本想到的都可以找到
3.apache更为成熟,少bug ,nginx的bug相对较多
4.apache超稳定,nginx稳定性差
5.apache对PHP支持比较简单,nginx需要配合其他后端用
6.apache在处理动态请求有优势,nginx在这方面是鸡肋,一般动态请求要apache去做,nginx适合静态和反向。
7.apache仍然是目前的主流,拥有丰富的特性,成熟的技术和开发社区
总结:
两者最核心的区别在于:
Apache是同步多进程模型,一个连接对应一个进程,而Nginx是异步的,多个连接(万级别)可以对应一个进程。
适用场景:
一般来说,需要性能的web服务,用Nginx;如果不需要性能只求稳定,更考虑Apache;
Nginx处理放静态内容比Apache要好,特别是在可承受压力、带宽及资源消耗上都要优于Apache。
所以更为通用的方案是,前端Nginx抗并发,后端Apache集群,配合起来会更好。
5、php描述
C语言开发的用于web网站建设的动态语言
从下到上4层处理:zend 引擎 + ext 扩展 + Sapi 接口 + php 程序
6、redis 、memcache、mongodb 描述 端口 6379
key-value nosql 非关系数据库、内从、磁盘、持久性、不丢失 、数据大1g
缓存、数据类型丰富、支持事务、原子性
功能:缓存、队列、排行榜/计数器、发布订阅、抢购,秒杀
memcache :缓存、功能单一 11211 、数据小1M
mongodb :最接近关系型数据库类型、文档存储 bsjon json 数据 27017
7、session 和 cookie
session 服务端 安全 通过cookie 存储 sessionid 要先开启session 关闭浏览器结束会话,太多影响服务器性能
cookie 客户端 不安全 不占用服务器资源
重要信息session 、次要信息cookie、 cookie支持跨域名访问、session不支持跨域名访问
共享方案:
1:使用数据库保存session, 使用数据库来保存session,就算服务器宕机了也没事,session照样在。
问题:程序需要定制;每次请求都进行数据库读写开销不小,另外数据库是一个单点,可以做数据库的hash来解 决这个问题。
2:使用 memcached来保存session, 这种方式跟数据库类似,内存存取性能比数据库好很多。
问题:程序需要定制,增加 了工作量;存入memcached中的数据都需要序列化,效率较低,断电或者重启电脑容易丢失数据;
3:使用 redis来保存session, 这种方式跟数据库类似,内存存取性能比数据库好很多。
问题:程序需要定制,增加 了工作量
4:通过加密的cookie,在A服务器上登录,在用户的浏览器上添加加密的cookie,当用户访问B服务器时,检查有无Session,如果没有,就检验 Cookie是否有效,Cookie有效的话就在B服务器上重建session。简单,高效, 服务器的压力减小了,因为session数据不存在服务器磁盘上。根本就不会出现session读取不到的问题。
问题:网络请求占用很多。每次请求时,客户端都要通过cookie发送session数据给服务器,session中数据不能太多,浏览器对cookie 的大
小存在限制。不适合高访问量的情况,因为高访问量的情况下。
8、include 和 require 区别
include 包含不存在不会报错,继续执行、有返回值
require 包含不存在会断开程序,建议用 require_once只引用一次、加载快
9、echo、print、print_r 、var_dump区别
echo 不是函数、没返回值、打印多个、可带可不带
print 函数、返回、打印一个、可带可不带
print_r 函数 返回、格式化值、打印一个、带括号
var_dump 函数 返回、类型、值、打印多个、带括号
10、冒泡排序
function msort($arr){
$len=count($arr);
for($i=0;$i<$len-1;$i++){
for($j=0;$j<$len-$i-1;$j++){
if($arr[$j]>$arr[$j+1]){
$tmp=$arr[$j];
$arr[$j]=$arr[$j+1];
$arr[$j+1]=$tmp;
}
}
}
return $arr;
}
$arr = [5,2,4,7,9,4,2,6,8,3];
11、自定义函数排序
function my_sort($a,$b)
{
if ($a==$b) {
return 0;
}
$s=$a>$b ? -1:1;
return $s;
}
$a5=array(4,2,2,6);
usort($a5,"my_sort");
12、常见数组函数
array(); 创建数组
count(); 统计数组元素
array_keys();获取数组key
array_values; 获取数组值
array_merge();合并数组
array_combine();合并数组
array_unique();数组唯一值
sort();数组排序顺序
rsort();倒序
array_pop;删除数组末尾元素
array_push();数组末尾添加元素
array_shift();头部删除
array_ushift();头部添加
array_filter();回调函数过滤数组中的元素
array_fill();填充数组
array_diff();差集
current();当前数组
in_array();在数组
is_array();判断
array_search();搜索
array_column();数组列
array_key_exists();判断key是否存在
13、常见字符串函数
sub_str();截取字符串
str_replace();字符串替换
strlen();长度
strtoupper();转大写
strtolower();转小写
strstr();搜索
strrev();翻转
ucwords();首字母大写
trim();去除空格
strpos();查找第一次位置
str_shuffle();随机打乱字符
14、用PHP打印出前一天的时间格式是2006-5-10 22:21:21
date('Y-m-d H:i:s', strtotime('-1 days'));
15、用PHP写出显示客户端IP与服务器IP的代码
打印客户端IP: $_SERVER['REMOTE_ADDR'];
打印服务器IP: gethostbyname("www.bolaiwu.com");
16、谈谈对mvc的认识 三层分离、代码重用、方便维护
由模型(model),视图(view),控制器(controller)完成的应用程序
控制器(调用模型、返回视图)轻量级、桥梁沟通作用,模型数据处理(数据库等、复杂业务处理),视图用户交互
17、框架中什么是单一入口和多入口 , 单一入口的优缺点?
多口就是通过访问不同的文件来完成用户请求。单一入口指 web 程序所有的请求都指向一个脚本文件的。
单一入口更容易控制权限,方便对 http 请求可以进行安全性检查。
缺点:URL 看起来不那么美观,特别是对搜索引擎来说不友好。
18、简述在MySQL数据库中MyISAM和InnoDB的区别
InnoDB存储引擎:
行锁设计、支持外键、支持事务;
MyISAM存储引擎:
不支持事务,支持表所和全文索引。查询速度快;
MyISAM存储引擎表由MYD和MYI组成,MYD用来存放数据文件,MYI用来存放索引文件。
MySQL数据库只缓存其索引文件,数据文件的缓存交给操作系统本身来完成;
MySQL5.0版本开始,MyISAM默认支持256T的单表数据;
19、 写出三种以上MySQL数据库存储引擎的名称(提示:不区分大小写)
MyISAM、InnoDB、Merge、Example 、CSV 等
20、 什么是面向对象?主要特征是什么?几大原则是什么?
面向对象是程序的一种设计模式,它利于提高程序的重用性,使程序结构更加清晰。 主要特征是:封装、继承、多态。
五大基本原则: 单一职责原则;开放封闭原则;替换原则; 依赖原则; 接口分离原则。
21、列举 Ajax 框架?说明 Ajax 实现原理是什么及 json 在 Ajax 中起什么作用?
jquery,局部刷新、异步提交,json 、xml数据格式
22、简单描述mysql中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)(新浪网技术部)
索引是一种特殊的文件 提高查询速度,但是会降低插入、删除、更新表的速度、占用内存
普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。
唯一索引 用关键字UNIQUE 定义具有唯一性如手机号
主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,
使用关键字 PRIMARY KEY 来创建。
索引可以覆盖多个数据列,如像INDEX(columnA, columnB)索引,这就是联合索引。
23.数据库中的事务是什么?
事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消。
ACID 四大特性,原子性(不可分离)、一致性(成功与否总的约束)、隔离性(锁机制记录)、持久性(一但提交保存到数据库)。
事务的(ACID)特性是由关系数据库管理系统(RDBMS,数据库系统)来实现的。
数据库管理系统采用日志来保证事务的原子性、一致性和持久性。日志记录了事务对数据库所做的更新,
如果某个事务在执行过程中发生错误,就可以根据日志,撤销事务对数据库已做的更新,使数据库退回到执行事务前的初始状态。
数据库管理系统采用锁机制来实现事务的隔离性。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。
24、为什么要对数据库进行主从分离?
一 什么是读写分离
部署主服务器和从服务器,主负责写、从负责读、减少服务器压力、加快速度
二 读写分离的好处
1.增加冗余
2.增加了机器的处理能力
3.对于读操作为主的应用,使用读写分离是最好的场景,因为可以确保写的服务器压力更小,而读又可以接受点时间上的延迟。
三 读写分离提高性能之原因
1.物理服务器增加,机器增加
2.主从只负责各自的写和读,(各司其职)
3.从库可配置myisam引擎,提升查询性能以及节约系统开销
4.从库同步主库的数据和主库直接写还是有区别的,通过主库发送来的binlog恢复数据,
但是,最重要区别在于主库向从库发送binlog是异步的,从库恢复数据也是异步的
5.读写分离适用与读远大于写的场景,如果只有一台服务器,当select很多时,update和delete会被这些select访问中的数据堵塞,等待select结束,并发性能不高。
对于写和读比例相近的应用,应该部署双主相互复制
6.分摊读取。拿机器换性能
7.MySQL复制另外一大功能是增加冗余,提高可用性,当一台数据库服务器宕机后能通过调整另外一台从库来以最快的速度恢复服务,因此不能光看性能,也就是说1主1从也是可以的。
25、 多线程和多进程的区别为?
当你运行一个程序,你就启动了一个进程。进程可以分为系统进程和用户进程。
凡是用于完成操作系统的各种功能的进程就是系统进程,它们就是处于运行状态下的操作系统本身;
所有由你启动的进程都是用户进程。进程是操作系统进行资源分配的单位。
在 Windows 下,进程又被细化为线程,也就是一个进程下有多个能独立运行的更小的单位(线程)。
26、cgi(每次请求结束会退出效率低下) 与fastcgi(开始启动添加进程不会不退出等待下一次请求效率高)的区别
cgi在2000年或更早的时候用得比较多, 以前web服务器一般只处理静态的请求,web服务器会根据这次请求的内容
然后会fork一个新进程来运行外部c程序 (或perl脚本...), 这个进程会把处理完的数据返回给web服务器,
最后web服务器把内容发送给用户,刚才fork的进程也随之退出。 如果下次用户还请求改动态脚本,
那么web服务器又再次fork一个新进程,周而复始的进行。
后来出现了一种更高级的方式是, web服务器可以内置perl解释器或php解释器。 也就是说这些解释器做成模块的方式,
web服务器会在启动的时候就启动这些解释器。 当有新的动态请求进来时,web服务器就是自己解析这些perl或php脚本,
省得重新fork一个进程,效率提高了。
fastcgi的方式是,web服务器收到一个请求时,他不会重新fork一个进程(因为这个进程在web服务器启动时就开启了,而且不会退 出),
web服务器直接把内容传递给这个进程(进程间通信,但fastcgi使用了别的方式,tcp方式通信),这个进程收到请求后进行处理,把结果返回 给web服务器,最后自己接着等待下一个请求的到来,而不是退出。
fastcgi跟cgi的区别是:
在web服务器方面 在对数据进行处理的进程方面
cgi fork一个新的进程进行处理 读取参数,处理数据,然后就结束生命期
fastcgi 用tcp方式跟远程机子上的进程或本地进程建立连接 要开启tcp端口,进入循环,等待数据的到来,处理数据
举个例子: 服务端现在有个10万个字单词, 客户每次会发来一个字符串,问以这个字符串为前缀的单词有多少个。 那么可以写一个程序,这个程序会建一棵trie树,然后每次用户请求过来时可以直接到这个trie去查找。
但是如果以cgi的方式的话,这次请求结束后这课trie也就没了,等下次再启动该进程时,又要新建一棵trie树,这样的效率就太低下了。
而用fastcgi的方式的话,这课trie树在进程启动时建立,以后就可以直接在trie树上查询指定的前缀了。
HTTP协议中几个状态码的含义。
200 : 请求成功,请求的数据随之返回。
301 : 永久性重定向。
302 : 暂时行重定向。
401 : 当前请求需要用户验证。
403 : 服务器拒绝执行请求,即没有权限。
404 : 请求失败,请求的数据在服务器上未发现。
500 : 服务器错误。一般服务器端程序执行错误。
503 : 服务器临时维护或过载。这个状态时临时性的。
写出一些php魔术方法。
__construct() 实例化类时自动调用。
__destruct() 类对象使用结束时自动调用。
__set() 在给未定义的属性赋值的时候调用。
__get() 调用未定义的属性时候调用。
__isset() 使用isset()或empty()函数时候会调用。
__unset() 使用unset()时候会调用。
__sleep() 使用serialize序列化时候调用。
__wakeup() 使用unserialize反序列化的时候调用。
__call() 调用一个不存在的方法的时候调用。
__callStatic()调用一个不存在的静态方法是调用。
__toString() 把对象转换成字符串的时候会调用。比如 echo。
__invoke() 当尝试把对象当方法调用时调用。
__set_state() 当使用var_export()函数时候调用。接受一个数组参数。
__clone() 当使用clone复制一个对象时候调用。
MySQL设计优化方案?
a. 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。
b. 选择合适的表字段数据类型和存储引擎,适当的添加索引。
c. mysql库主从读写分离。
d. 找规律分表,减少单表中的数据量提高查询速度、分区、分表。
e. 添加数据缓存机制,比如memcached,redis。
f. 不经常改动的页面,生成静态页面。
g. 书写高效率的SQL。
说下php中empty()和isset()的区别。
isset 用于检测变量是否被设置,使用 isset() 测试一个被设置成 NULL 的变量,将返回 FALSE 。
empty 如果 var 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE 。
如果变量为 0 ,则empty()会返回TRUE,isset()会返回TRUE;
如果变量为空字符串,则empty()会返回TRUE,isset()会返回TRUE;
如果变量未定义,则empty()会返回TRUE,isset()会返回FLASE。
注意:isset() 只能用于变量,因为传递任何其它参数都将造成解析错误。若想检测常量是否已设置,可使用 defined() 函数。 当要 判断一个变量是否已经声明的时候 可以使用 isset 函数;
当要 判断一个变量是否已经赋予数据且不为空 可以用 empty函数;
当要 判断 一个变量 存在且不为空 先 isset 函数 再用 empty 函数;
31、HTTP Keep-Alive的作用
作用:Keep-Alive:使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。Web服务器,基本上都支持HTTP Keep-Alive。
缺点:对于提供静态内容的网站来说,这个功能通常很有用。但是,对于负担较重的网站来说,虽然为客户保留打开的连 接有一定的好处,但它同样影响了性能,因为在处理暂停期间,本来可以释放的资源仍旧被占用。当Web服务器和应用服务器在同一台机器上运行时,Keep- Alive功能对资源利用的影响尤其突出
解决:Keep-Alive: timeout=5, max=100
timeout:过期时间5秒(对应httpd.conf里的参数是:KeepAliveTimeout),max是最多一百次请求,强制断掉连接。就是在timeout时间内又有新的连接过来,同时max会自动减1,直到为0,强制断掉。
32、php获取文件内容的方法,对应的函数
1:file_get_contents得到文件的内容(可以以get和post的方式获取),整个文件读入一个字符串中
2:用fopen打开url, 以get方式获取内容(借助fgets()函数)
3:用fsockopen函数打开url(可以以get和post的方式获取),以get方式获取完整的数据,包括header和body
4:使用curl库获取内容,使用curl库之前,需要查看php.ini,查看是否已经打开了curl扩展
34、什么是跨站脚本?SQL注入?
跨站脚本( XSS )是一种计算机安全漏洞,是代码注入的一种,通常出现在web应用程序上。
它允许恶意用户将代码注入到网页上,其他用户观看网页时就会收到影响。这种攻击通常包含了html以及客户端脚本语言。
SQL 注入是发生于应用程序数据库层的安全漏洞。是在输入的字符中注入 SQL 指令,在设计不良的程序中忽略了检查,
那么这些注入的指令会被数据库误认为是正常的 SQL 指令而运行,因此遭到破坏
35、PHP内存管理机制与垃圾回收机制
php 的内存管理机制是:预先给出一块空间,用来存储变量,当空间不够时,再申请一块新的空间。
变量名,存在符号表。
变量值存储在内存空间。
在删除变量的时候,会将变量值存储的空间释放,而变量名所在的符号表不会减小。
php 垃圾回收机制是:php5.2 引用技术值为0 直接清理 php5.3 值为0清理,值在减少不为0放入缓存,缓存满了自动清理
在5.2版本或之前版本,PHP会根据 引用计数 ( refcount )值来判断是不是垃圾,如果refcount值为0,PHP会当做垃圾释放掉,这种回收机制有缺陷,对于环状引用的变量无法回收。
在5.3之后版本改进了垃圾回收机制。具体如下:
如果发现一个 zval 容器中的 refcount 在增加,说明不是垃圾; 如果发现一个 zval 容器中的 refcount 在减少,如果减到了0,直接当做垃圾回收; 如果发现一个 zval 容器中的 refcount 在减少,并没有减到0,PHP 会把该值放到缓冲区,当做有可能是垃圾的怀疑对象; 当缓冲区达到了临界值,
PHP 会自动调用一个方法去遍历每一个值,如果发现是垃圾就清理。
36、PHP7新特性(部分示例)
(1)标量类型声明
默认情况下,所有的PHP文件都处于弱类型校验模式。
PHP 7 增加了标量类型声明的特性,标量类型声明有两种模式:
强制模式 (默认)
严格模式
标量类型声明语法格式:
declare(strict_types=1);
代码中通过指定 strict_types的值(1或者0),1表示严格类型校验模式,作用于函数调用和返回语句;
0表示弱类型校验模式。
(2) void 函数
一个新的返回值类型void被引入。 返回值声明为 void 类型的方法要么干脆省去 return 语句,要么使用一个空的 return 语句。 对于 void 函数来说,NULL 不是一个合法的返回值。
返回的类型还有 void,定义返回类型为 void 的函数不能有返回值,即使返回 null 也不行。
void 函数可以省去 return 语句,或者使用一个空的 return 语句。
(3)新增太空船运算符如果 $a 小于、等于或大于 $b时,它分别返回-1、0或1 print( 1 <=> 1);print(PHP_EOL);
PHP 7 新增加的太空船运算符(组合比较符)用于比较两个表达式 $a 和 $b,如果 $a 小于、等于或大于 $b时,它分别返回-1、0或1(组合比较符)用于比较两个表达式 $a 和 $b,如果 $a 小于、等于或大于 $b时,它分别返回-1、0或1
(4)PHP NULL 合并运算符 三元运算符 $site = $_GET['site'] ?? '菜鸟教程';
(5)PHP 常量数组 在 PHP 5.6 中仅能通过 const 定义常量数组,PHP 7 可以通过 define() 来定义。
(6)PHP 7 可以使用一个 use 从同一个 namespace 中导入类、函数和常量:
(7)移除部分扩展 如MySQL
37、双引号和单引号的区别
双引号解释变量,单引号不解释变量
双引号里插入单引号,其中单引号里如果有变量的话,变量解释
双引号的变量名后面必须要有一个非数字、字母、下划线的特殊字符,或者用{}讲变量括起来,否则会将变量名后面的部分当做一个整体,引起语法错误
双引号解释转义字符,单引号不解释转义字符
单引号的效率比双引号要高(因为双引号要先遍历一遍,判断里面有没有变量,然后再进行操作,而单引号则不需要判断)
38、常用的超全局变量(8个)
$_GET ----->get传送方式
$_POST ----->post传送方式
$_REQUEST ----->可以接收到get和post两种方式的值
$GLOBALS ----->所有的变量都放在里面
$_FILE ----->上传文件使用
$_SERVER ----->系统环境变量
$_SESSION ----->会话控制的时候会用到
$_COOKIE ----->会话控制的时候会用到
39、PHP处理时间的常用函数?(重点看函数的‘参数’和‘返回值’)
date_default_timezone_get()返回默认时区。
date_default_timezone_set()设置默认时区。
date()格式化本地时间/日期。
getdate()返回日期/时间信息。
gettimeofday()返回当前时间信息。
microtime()返回当前时间的微秒数。
mktime()返回一个日期的 Unix时间戳。
strtotime()将任何英文文本的日期或时间描述解析为 Unix时间戳。
time()返回当前时间的 Unix时间戳。
40、 什么是锁?针对并发处理、加锁释放之前别人不可修改数据
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。
若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,
先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,
其他的事务不能对此数据对象进行更新操作。
基本锁类型:锁包括行级锁和表级锁
41、面向对象的特征有哪些方面?
主要有封装,继承,多态。如果是4个方面则加上:抽象。
下面的解释为理解:
封装:(模块化)
封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的高内聚,低耦合,防止程序相互依赖性而带来的变动影响.
继承:(重用)
在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。
多态:(动态获取)
多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
抽象:(共性)
抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。
42、说说下面这些这些协议的全称和中文解释(提示:都是工作在应用层)SMTP、POP3、HTTP、FTP、DNS
SMTP (Simple Mail Transfer Protocol) 简单邮件传输协议
POP3 (Post Office Protocol 3) 邮局协议第3版
HTTP (Hypertext Transfer Protocol) 超文本传输协议
FTP (File Transfer Protocol)文件传输协议
DNS (Domain Name System and Domain Name Service protocol) 域名系统(服务)协议
43、请介绍一下laravel框架?
答: laravel框架的设计思想比较先进,非常适合应用各种开发模式,作为一个框架,它为你准备好了一切
laravel框架最大的特点和优秀之处就是集合了php比较新的特点,以及各种各样的设计模式,Ioc模式,依赖注入等
laravel有那些特点?
回答一:
1.强大的rest router:用简单的回调函数就可以调用,快速绑定controller和router
2.artisan:命令行工具,很多手动的工作都自动化
3.可继承的模板,简化view的开发和管理
4.blade模板:渲染速度更快
5.ORM操作数据库
6.migration:管理数据库和版本控制
7.测试功能也很强大
8.composer也是亮点
回答二: laravel框架引入了门面,依赖注入,Ioc模式,以及各种各样的设计模式等
44.怎么保证促销商品不会超卖?
答:这个问题是我们当时开发时遇到的一个难点,超卖的原因主要是下的订单的数目和我们要促销的商品的数目不一致导致的,每次总是订单的数比我们的促销商品的数目要多,当时我们的小组讨论了好久,给出了好几个方案来实现:
第一种方案:在每次下订单前我们判断促销商品的数量够不够,不够不允许下订单,更改库存量时加上一个条件,只更改商品库存大于0的商品的库存,当时我们使用ab进行压力测试,当并发超过500,访问量超过2000时,还是会出现超卖现象。所以被我们否定了。
第二种方案:使用mysql的事务加排他锁来解决,首先我们选择数据库的存储引擎为innoDB,使用的是排他锁实现的,刚开始的时候我们测试了下共享锁,发现还是会出现超卖的现象。有个问题是,当我们进行高并发测试时,对数据库的性能影响很大,导致数据库的压力很大,最终也被我们否定了。
第三种方案:使用文件锁实现。当用户抢到一件促销商品后先触发文件锁,防止其他用户进入,该用户抢到促销品后再解开文件锁,放其他用户进行操作。这样可以解决超卖的问题,但是会导致文件得I/O开销很大。
最后我们使用了redis的队列来实现。将要促销的商品数量以队列的方式存入redis中,每当用户抢到一件促销商品则从队列中删除一个数据,确保商品不会超卖。这个操作起来很方便,而且效率极高,最终我们采取这种方式来实现
45、商城秒杀的实现?
答:抢购、秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:
1 高并发对数据库产生的压力
2 竞争状态下如何解决库存的正确减少("超卖"问题)
对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis。
第二个问题,我们可以使用redis队列来完成,把要秒杀的商品放入到队列中,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,文件锁和事务在高并发下性能下降很快,当然还要考虑其他方面的东西,比如抢购页面做成静态的,通过ajax调用接口,其中也可能会出现一个用户抢多次的情况,这时候需要再加上一个排队队列和抢购结果队列及库存队列。高并发情况下,将用户进入排队队列,用一个线程循环处理从排队队列取出一个用户,判断用户是否已在抢购结果队列,如果在,则已抢购,否则未抢购,库存减1,写数据库,将用户入结果队列。
46、Mysql 分区(比较简单不改代码)、分表(复杂指定表)、分库(复杂指定库)对比
基本概念
数据库分表(分表和分区相比)
分表更复杂,但是性能稍微好一点点。但是如果Mysql可以高效的维护各个分区之间的关系的话,其实分表是没有必要的。错误的分表操作,会带来bug
分表的性能更好,不需要查询优化器来选择读取哪张表,但是分表编码更复杂,要通过代码指定数据存储到特定的表
数据库分库:(物理层面进行拆分)
读写分离:把读和写进行拆分,优势是没有分布式事务的问题,同时编程简单,通过中间件像操作一个数据库一样
不同业务的拆分:编程复杂(根据业务选择对应的数据库),做关联业务联级操作的时候,有分布式事务的问题
一个大业务拆分为若干个子业务:编程复杂,分布式事务更严重
如何提升并发写的效率?
已经基于行级锁的话,就没有办法从软件层面提升并发度了,否则会事务冲突。所以思路:行级锁、物理层面提升。
弃用Myisam,改用Innodb,基于索引的行级锁技术,支持操作一张表时,并发的写(注意行级锁的使用,尽量避免表锁)
读写分离,让主库专注于写,让从库专注于读取(物理提升)
数据库分库:把不同的业务拆分到不同的数据库,甚至可以把同一个业务拆分在不同的数据库,引入了编程复杂(根据业务选择对应的子库)和分布式事务的问题(物理提升)
如何提升并发读的效率?
SQL优化、索引、缓存、参数配置
架构调整:分区、分表、分库(读写分离或者业务拆分)
读写分离主从复制的优势
主从复制,解决的是容灾类的问题,容灾需要保证数据库切换的实时性和数据的一致性,主机挂了的时候,可以借助中间件,让从机上升为Master
读写分离,同时提升了数据库单机的读和写的能力,主库负责写和极少部分的即时性要求高的读,从而提升写的性能。从数据库只要负责读,通过二进制日志的形式批量写,并保持数据和主库一致,合作分工,同时提升读写的性能
负载均衡,一主多从下,从库是水平扩展了多个数据库来分摊读的请求(即时性要求不高的读请求),以前一台数据库既负责读又负责写,现在多台数据库分摊读的请求
适用场景:大部分的读操作对数据的实时性要求并没有那么高,一般对时延的容忍在秒级以上
读写分离的本质:用硬件资源和带宽换性能。
Mysql 分区、分表、分库PK
分区、分表、分库都可以大幅提升数据库读的性能。
数据库分库可以提升并发写的速度:通过简单暴力的物理方式拆分功能
分区最简单,由数据库自身维护数据关系;分表复杂,需要开发人员指定数据读写在哪张子表;分库最复杂,除了为对应的数据选择对应的数据库以外,还需要解决跨库的分布式事务问题
分区、分表、分库并不冲突,比如在 读写分离的业务场景,对读的数据库的某些表进行分区或者分表。或者对于一些容易编程的表用分表,编程复杂的业务用分区,都是可行的
其它
如果一个业务复杂到分区分表分库仍然解决不了的话,基本上不会出现,一般到了这种量级的数据,早就微服务了,业务拆分,各自业务维护自己的数据库。
47、PHP是什么?
服务端脚本语言web、java,c 模式fpm:普通模式.cli:常驻内存 swoole
48、请求 =》查找缓存 =》域名解析 dns=》服务器建立联系 1、发送-》2、收到并返回=》3、客户端确认 3次握手4次挥手
49、MySQL 查询顺序 1、from 2、where 3、group by 4、having 5、select 字句 6、order by 字句
50、主从分离:主读,从写减少服务器压力加快速度,读写分离,采用不通数据类类型,异步同步,binlog日志
51、接口设计:安全性(保证安全可靠),可维护性(版本控制),可扩展性(版本),一致性(返回结构),能抗高并发,易用性(简单使用)
简单易用:API 应该简单、易懂、易使用,用户可以快速上手并掌握使用方法。
一致性:API 的接口和参数应该保持一致性,在不同的场景下使用类似的设计规则,这样可以帮助用户更容易理解和使用。
易于扩展:API 应该允许新的功能和资源被添加到系统中,而不会破坏现有的结构或接口。
安全性:API 应该设计为安全的,采用加密方式来传输敏感信息,并通过身份验证等机制来保护数据安全。
高效性:API 应该具有高效性和优化性能,尽可能减少响应时间和网络延迟。可测试性:API 应该是可测试的,可以提供测试工具和环境以便开发人员进行测试和调试。
文档化:API 应该提供详细的文档和示例代码,以便开发人员使用和集成到自己的应用程序中。
错误处理:API 应该提供合适的错误处理机制,包括错误消息、代码、HTTP 状态码等信息,以便对错误进行调试与处理。不断优化,不断思考,不断尝试