百度外卖PHP面试
2018-01-10 本文已影响108人
血之君殇
- 数据库事务的四个特性
- 原子性
- 一致性
- 隔离性
- 持久性
- 数据库事务的隔离级别
- 事务执行过程中,可能会出现以下几种情况:
- 更新丢失
两个事务都同时更新一行数据,一个事务对数据的更新把另一个事务对数据的更新覆盖了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。 - 脏读
一个事务读取到了另一个事务未提交的数据操作结果。 - 不可重复读
一个事务对同一行数据重复读取两次,但是却得到了不同的结果。
(1) 虚读:事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。
(2) 幻读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。
- 更新丢失
- 事务隔离级别的区别以及可能出现的问题:
- Read uncommitted(未授权读取、读未提交):
如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。避免了更新丢失,却可能出现脏读。也就是说事务B读取到了事务A未提交的数据。 - Read committed(授权读取、读提交):
读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。该隔离级别避免了脏读,但是却可能出现不可重复读。事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。 - Repeatable read(可重复读取):
读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。避免了不可重复读取和脏读,但是有时可能出现幻读。这可以通过“共享读锁”和“排他写锁”实现。 - Serializable(序列化):
提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。序列化是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻像读。
- Read uncommitted(未授权读取、读未提交):
- 大多数数据库的默认级别就是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别就是Repeatable read。
- 事务执行过程中,可能会出现以下几种情况:
- 乐观锁和悲观锁
悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。
两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。 - 写两条SQL语句造成死锁
只想到了一个进程需要AB两张表,另一个进程需要BA两张表,然后各锁一个表,互相等待,导致死锁 -
PHP的生命周期
php生命周期.png - fast-cgi
Fastcgi是CGI的升级版,一种语言无关的协议,用来沟通程序(如PHP, Python, Java)和Web服务器(Apache2, Nginx), 理论上任何语言编写的程序都可以通过Fastcgi来提供Web服务。
Fastcgi的特点是会在一个进程中依次完成多个请求,以达到提高效率的目的,大多数Fastcgi实现都会维护一个进程池。
而PHP-fpm就是针对于PHP的,Fastcgi的一种实现,他负责管理一个进程池,来处理来自Web服务器的请求。目前,PHP-fpm是内置于PHP的。 - xargs
xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。xargs的默认命令是echo,空格是默认定界符。这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。xargs是构建单行命令的重要组件之一。上次的awk命令就没记住,这次这个估计也是记不住 - 显示一个文件的最后10行
cat filename | tail -n 1000 - PHP的5个数组处理函数
函数 | 描述 |
---|---|
array_count_values() | 用于统计数组中所有值出现的次数。 |
array_merge() | 把一个或多个数组合并为一个数组。 |
array_shift() | 删除数组中首个元素,并返回被删除元素的值。 |
array_push() | 将一个或多个元素插入数组的末尾(入栈)。 |
array_map() | 把数组中的每个值发送到用户自定义函数,返回新的值。 |
- PHP的5个字符串处理函数
函数 | 描述 |
---|---|
str_replace() | 替换字符串中的一些字符(对大小写敏感)。 |
str_split() | 把字符串分割到数组中。 |
str_word_count() | 计算字符串中的单词数。 |
substr() | 返回字符串的一部分。 |
trim() | 移除字符串两侧的空白字符和其他字符。 |
- 有一个100个元素的数组,里面只有两个值加起来是50,求这两个值
<?php
$arr = [28, 22];
for ($i = 0; $i < 98; $i++) {
array_push($arr, rand(0, 1000));
}
function quick_sort($ds)
{
if (count($ds) <= 1) {
return $ds;
} else {
$left = [];
$right = [];
for ($i = 1; $i < count($ds); $i++) {
if ($ds[$i] < $ds[0]) {
array_push($left, $ds[$i]);
} else {
array_push($right, $ds[$i]);
}
}
$left = quick_sort($left);
$right = quick_sort($right);
return array_merge($left, [$ds[0]], $right);
}
}
function getSumNum($arr, $Sum)
{
for ($i = 0, $j = count($arr) - 1; $i < $j;) {
$tmp = $arr[$i] + $arr[$j];
if ($tmp == $Sum) {
return [$arr[$i], $arr[$j]];
} else if ($tmp < $Sum) {
$i++;
} else {
$j--;
}
}
return [];
}
$arr = quick_sort($arr);
print_r($arr);
$result = getSumNum($arr, 50);
print_r($result);