1. 说说你对进程, 线程以及协程的理解
进程: 是系统进行资源分配和调度的基本单位, 是基本操作系统结构的基础. 进程是程序基本执行的实体. 进程与进程之间是独立的, 拥有完全独立的地址空间, 进程的切换只发生在内核态, 由操作系统调度.
线程: 线程是操作系统进行运算调度的最小单位. 它被包含在进程之中, 是进程中实际运作的运行单位. 一条线程指的是进程中一个单一顺序的控制流, 一个进程中可以并发多个线程, 每条线程并行执行不同的任务.
协程: 是一种用户态的轻量级线程, 协程的调度完全由用户控制. 携程拥有自己的寄存器上下文和栈. 协程调度切换时, 将寄存器上下文和栈保存在其它地方, 在切回来的时候, 恢复之前保存的寄存器上下文和栈, 直接操作栈则基本没有内核切换的开销, 可以不加锁的访问全局变量, 所以上下文切换的非常快, 执行协程只需要极少的栈内存.
2. 请比较下 Memcached,Redis, 并说明下 Redis 的常见应用场景
1.Redis 支持的数据类型比较多不仅支持常见 k/v 类型还支持 list,set,hash 等类型, 它比 Memcached 更像数据库
2.Memcached 只是简单的 key/value 的缓存, 被用来做常规的缓存处理
3.Memcached 不支持持久化存储, 它把全部数据存储在内存中, 断电或重启时数据会掉
4.Redis 支持数据持久化, 所以断电或者重启后之前落地的数据还可以找到
5.Redis 支持数据的备份, 即 master-slave 模式的数据备份, Memcached 可以使用一致性 hash 做分布式
6.Redis 使用的是单线程模型, 保证了数据按顺序提交, Memcached 使用的是 cas 保证数据一致性. cas(check and set)是一个确保并发一致性的机制, 属于 "乐观锁" 范畴; 原理就是拿版本号, 操作对比版本号, 如果一致就操作不一致就放弃.
Redis 常见应用场景:
排行榜: 如果使用传统的关系型数据库来做这个事儿, 还是有点麻烦的, 如果使用 Redis 的 sortSet 数据结构能够非常方便搞定.
计数器 / 限速器: Redis 中原子性的强悍的自增操作, 可以用来统计点赞数, 文章的阅读数, 以及电商活动中的秒杀抢购中房子用户疯狂点击所带来的不必要的压力
好友关系: 使用集合的求交集, 并集, 差集可以方便处理共同好友, 相同爱好等一些功能
简单的消息队列: 如果使用 MySQL 来做无疑会对 db 产生一些压力, 如果针对不是特别大队列任务处理的话, 可以使用 Redis 的消息队列功能, 将一些需求和任务写到 Redis 队列, 异步处理
session 共享: 这个其实是针对分布式部署来说的, session 一般是保存在服务器中的, 如果流量请求分摊到多台服务器后, 这样用户的会话就会产生问题, 这个时候可以通过 PHP 的配置来将 session 统一存储在 Redis 中来报错 session 的统一性.
3.MySQL 中的 myisam 和 innodb 数据库存储引擎的区别
1, 存储结构
myisam: 存储数据落在三个文件..FRM 文件存储表定义,.MYD 数据文件,.MYI 索引文件.
innodb: 存储在两个文件,.frm 存储表定义,.ibd 其它数据
2, 存储空间
myisam: 可被压缩, 存储空间较小
innod: 需要更多的内存和存储空间
3, 可移植性, 备份及恢复
myisam: 数据是以文件形式存储, 可移植性强, 直接拷贝文件即可.
innodb: 使用 binlog,mysqldump 备份, 数据过大就比较费时比较痛苦
4, 事务支持
myisam: 强调性能查询速度快, 不支持事务
innodb: 支持事务, 外键等功能
5,AUTO_INCRMENT
myisam: 可以和其它字段建立联合索引
innodb: 具有自动增长的字段索引必须是独立的, 如果和其它字段组合必须排在第一列
6, 锁
myisam: 只支持表级锁
innodb: 支持事务和行级锁. 但是 innodb 的行锁, 只是在 where 的主键是有效的, 非主键 where 会锁全表
7, 全文索引
myisam: 支持 FULLTEXT 类型的全文索引
innodb: 不支持 FULLTEXT 全文索引, 不过可以使用其它第三方的引擎支持比如 Sphinx
8, 表主键
myisam: 允许没有任何索引和主键的存在, 索引都是保持行的地址
innod: 如果没有设置主键, 会自动创建一个用户不可见 6 直接的主键, 数据是主索引的一部分, 附加索引保存的是主索引的值
9, 表的具体行数
myisam: 保存有表的总行数, 如果 select count, 会直接取出快速
innodb: 没有直接保持总行数, 查询所有需要遍历整个表, 若增加 where 条件后跟 myisam 处理方式一样
10,CURD 操作
myisam: 大量查询适合使用该引擎
innod: 大量的 insert,update 适合使用该引擎.
11, 外键
myisam: 不支持外键
innodb: 支持外键功能
4. 阐释数据库事务的 ACID 的四个特性
原子性(Atomicity): 一个事务必须被视为一个不可分割的最小工作单元, 整个事务中的所有操作要么全部提交完成, 要么全部失败回滚, 对于一个事务来说, 不可能只执行其中的一部分操作.
一致性(Consistency): 数据库总是从一个一致性的状态转换到另一个一致性的状态.
隔离性(Isolation): 一个事务所做的修改在最终提交之前, 对其它事务是不可见的.
持久性(Durability): 一旦事务提交, 则其修改会永远的保存在数据库中.
5. 阐述 MySQL 的 4 种隔离级别
读未提交(read-uncommitted): 事务可以读取未提交的数据, 这也被称为脏读.
读提交(read-committed): 一个事务从开始直到事务提交之前, 所做的任何修改对其他事务都是不可见的.
可重读(repeatable-read)MySQL 默认事务级别: 当某个事务在读取某个范围内的记录时, 另外一个事务又在该范围内插入了新的记录, 当之前的事务再次读取该范围的记录时, 会产生幻读.
可串行化 (serializable) 最高事务级别: 避免了前面说的幻读, 即在读取没一行数据上都加锁, 所以可能导致大量的超时和锁争用的问题.
6.select count(*),select count(1),select(column)的区别
1. 一般情况下 select count(*)与 select count(1)结果和速度是一样的, 即查询所有
2.count(column)对特定的值具有行数进行计算, 不包含空值, 所以结果可能会有些不一样 (可能会比 count(*) 统计的要少)
3.count(*)对行的数目进行计算, 包括 null
4. 如果没有主键, 那么 count(1)要比 count(*)快
5. 如果表中只有一个字段, count(*)最快
6. 一般来说大多情况下 count(*)是最优的选择
7. 如果理解 oop?
oop 即面向对象编程, 在面向对象编程中最重要的两个概念就是类和对象.
时间万物都有其属性和特点或者说特性, 我们将这些属性特性进行整合起来形成一个类, 比如具有猫科类的特点和属性的我们称为猫科类. 这个时候猫科类只是具有这类的属性的抽象模型, 如果要具体要是那种猫或者说需要得到一个具体的实体这个时候就需要对类进行实例化, 类在实例化后就是对象了, 此时的猫就是一个更加具体存在的对象.
在编程世界里, 就是通过这种思想将具有相同的属性的和特性进行就行管理, 组合生一个类, 类中有对应的属性和实现的方法, 通过一些初始化和实例化, 或者调用一些方法来达到我们需要的功能.
面向对象中有三大特点:
1. 封装性
也成为隐藏性, 就是将使用和具体实现分开, 只对外开放部分接口和方法与外部联系, 或者说只公开一部分供开发人员使用的方法和参数.
2. 继承性
子类自动继承父类的属性和方法, 并可以通过添加新的属性和方法来对部分属性和方法进行重写, 这样增加了代码的重用性.
3. 多态性
虽然说父类只有一个, 但是可以有多个子类, 这些子类中虽然调用的相同的属性或者方法, 但是由于继承性这个的存在和重写, 实例化后这些子类却可以或者完全不同的结果, 得到不同形态的东西, 这种技术就是多态性.
8. 请阐述 http 与 https 的区别
1.https 协议需要到 ca 申请证书, 一般免费证书较少, 因而需要一定费用
2.http 是超文本传输协议, 信息是明文传递, https 则是更具有安全性的 ssl 加密传输协议
3.http 和 https 使用的是完全不同的连接方式, 用的端口也不一样, 前者是 80 后者是 443
4.http 的连接很简单, 是无状态的, https 协议是由 http+ssl 协议构建的可进行加密传输, 身份认证的网络协议, 比 http 协议安全
9. 使用 PHP 的三种方式获指定取路径下的文件夹和文件
方法一: 通过 opendir 获取资源句柄, 再使用 readdir 函数并遍历获取
- $dir = "/data/wwwroot/test";
- function oneReadDirs($dir){
- $handle = opendir($dir);
- $outStr = '';
- while(($item = readdir($handle))!==false){
- if($item!='.' && $item!='..' ){
- $path = $dir.'/'.$item;
- if(is_file($path)){
- $outStr .= '[文件]'.$item.PHP_EOL;
- }elseif(is_dir($path)){
- $outStr .= '[目录]'.$item.PHP_EOL;
- }
- }
- }
- return $outStr;
- }
- $dirs = oneReadDirs($dir);
- echo $dirs;
方法二: 使用 scandir 一次性获取路径下的所有文件夹和文件再进行处理
- function twoReadDirs($dir){
- $dirs = scandir($dir);
- $outStr = '';
- foreach($dirs as $k=>$v){
- $path = $dir.'/'.$v;
- if($v!=='.' && $v!=='..' ){
- if(is_file($path)){
- $outStr .= '[文件]'.$v.PHP_EOL;
- }elseif(is_dir($path)){
- $outStr .= '[目录]'.$v.PHP_EOL;
- }
- }
- }
- return $outStr;
- }
- $dirs2 = twoReadDirs($dir);
- echo $dirs2;
方法三: 使用面向对象的 dir 处理方式获取
- function threeReadDirs($dir){
- $d = dir($dir);
- $outStr = '';
- while(($item = $d->read())!==false){
- if($item!='.' && $item!='..' ){
- $path = $dir.'/'.$item;
- if(is_file($path)){
- $outStr .= '[文件]'.$item.PHP_EOL;
- }elseif(is_dir($path)){
- $outStr .= '[目录]'.$item.PHP_EOL;
- }
- }
- }
- $d->close();
- return $outStr;
- }
- $dirs3 = threeReadDirs($dir);
- echo ($dirs3);
输出结果为:
[目录] App
[文件] index.html
[目录] cache
[文件] .htaccess
[目录] .phalcon
[目录] public
10. 写一个函数算出两个文件的相对路径
- $path1 = '/a/b/c/d/e/f/g/h/e.php';
- $path2 = '/a/b/1/2/c.php';
- function getRelativePath($path1, $path2){
- $arr1=explode('/',dirname($path1));
- $arr2=explode('/',dirname($path2));
- for($i=0, $len=count($arr2); $i<$len; $i++ ){
- if($arr1[$i]!=$arr2[$i]){
- break ;
- }
- }
- if($i<$len){
- $return_path=array_fill(0,$len-$i,'..');
- }
- //$path1 相对于 $path2
- $return_path=array_merge($return_path,array_slice($arr1,$i));
- return implode('/',$return_path);
- }
- echo getRelativePath($path1,$path2);
- //../../c/d/e/f/g/h
来源: https://www.cnblogs.com/lisqiong/p/10075614.html