一、面试问题
1、安全方面
- 介绍一下开发过程中会遇到的安全问题
XSSCRRF
任意文件下载
ssrf
- 针对每一个安全问题如何解决
- 微信登录、微博登录使用的是什么协议?原理是什么
2、数据库
- 简单描述mysql中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)
索引就相当于对指定的列进行排序,排序有利于对该列的查询,可以大大增加查询效率
建立索引也是要消耗系统资源,所以索引会降低写操作的效率
主键,唯一,联合都属于索引
主键属于唯一索引,且一个表只能有一个主键,主键列不允许空值
唯一索引可以一个表中可以有多个,而且允许为空,列中的值唯一
多个字段的多条件查询多使用联合索引
- MyISAM与InnoDB数据库引擎的区别
1、 存储结构
MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。
2、 存储空间
MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。
InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。
3、 可移植性、备份及恢复
MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。
4、 事务支持
MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
5、 AUTO_INCREMENT
MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列。
6、 表锁差异
MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。
InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。
7、 全文索引
MyISAM:支持 FULLTEXT类型的全文索引
InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。
8、 表主键
MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。
9、 表的具体行数
MyISAM:保存有表的总行数,如果select count() from table;会直接取出出该值。
InnoDB:没有保存表的总行数,如果使用select count() from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。
10、 CURD操作
MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。
11、 外键
MyISAM:不支持
InnoDB:支持
通过上述的分析,基本上可以考虑使用InnoDB来替代MyISAM引擎了,原因是InnoDB自身很多良好的特点,比如事务支持、存储 过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。另外,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,这个具体情况可以自己斟酌。
存储引擎选择的基本原则
采用MyISAM引擎
R/W > 100:1 且update相对较少
并发不高
表数据量小
硬件资源有限
采用InnoDB引擎
R/W比较小,频繁更新大字段
表数据量超过1000万,并发高
安全性和可用性要求高
采用Memory引擎
有足够的内存
对数据一致性要求不高,如在线人数和session等应用
需要定期归档数据
3、框架
- 谈一谈 PHP 开源框架 CI,ThinkPHP,Laravel 的优缺点及选型依据
CI非常轻量级,是一个简单的MVC框架,性能也很快。
ThinkPHP3.2国内使用比较多,优点是文档非常多,各种问题解决方案比较多,缺点是代码不够规范,理念落后。
Laravel 是一个现代化的PHP开发框架,代码优雅,使用 composer 方式扩展功能,社区活跃,缺点是比较重,比较适合做后台管理或者应用型WEB系统。
- 是否还用过其他框架?symfony?phalcon?
- 什么是模版引擎?用过什么模版引擎?
Smarty
twig
4、代码规范/质量/设计模式
- 列举常用的设计模式并说明一下什么情况下使用什么设计模式?
策略模式
> 定义个策略接口,不同的实现类提供不同的具体策略算法, 同时它们之间可以互相替换.
简单工厂模式
> 定义一个用以创建对象的工厂, 根据不同的条件生成不同的对象
工厂模式
> 针对每一种产品提供一个工厂类,通过不同的工厂实例来创建不同的产品实例
抽象工厂模式
> 应对产品族概念而生
装饰者模式
> 动态的给一个对象添加一些额外的功能
代理模式
> 封装被代理对象并限制外界对被代理对象的访问
模板方法模式
> 定义一个操作的算法骨架, 并将一些步骤延迟到子类中
外观模式
> 为系统向外界提供一个统一的接口
适配器模式
> 将一个类的接口转换成客户希望的另一个接口
桥接模式
> 将抽象部分与实现部分分离,使它们都可以独立的变化
建造者模式
> 将一个复杂对象的构建与它的表示分离.
观察者模式
> 定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,在它的状态发生变化时,会通知所有的观察者.
单例模式( Singleton )
> 保证一个类仅有一个实例,并提供一个访问它的全局控制点.
命令模式( Command )
> 将一个请求封装成为一个对象, 使可以用不同的请求对客户进行参数化
- 是否实践过PHP编码规范?
https://psr.phphub.org/
- 是否了解重构?介绍几种常用的重构方法
重组函数
* 抽取变量
* 抽取方法
* 内联方法
* 查询取代临时变量
* 分解临时变量
* 移除对参数赋值
* 以函数对象取代函数
* 内联临时变量
* 替换算法
搬移特性
* 搬移字段
* 搬移函数
* 隐藏委托关系
* 提炼类
* 内联类
* 引入外加函数
* 引入本地扩展
* 移除中间人
组织数据
* 自封装字段
* 以对象取代数组
* 以对象取代数据值
* 复制被监视数据
* 将值对象改为引用对象
* 单向关联到双向关联
* 双向关联到单向关联
* 引用对象改为值对象
* 字面常量取代魔法数
* 封装字段
* 封装集合
* 数据类取代记录
* 子类取代代码类型
* 类型取代类型码
* 字段取代子类
* State/Strategy 取代类型码
简化条件
* 分解条件表达式
* 卫语句取代嵌套条件
* 合并条件表达式
* 多台取代条件
* 合并重复条件片段
* 引入null对象
* 移除控制标记
* 引入断言
简化函数调用
* 函数改名
* 零函数携带参数
* 添加参数
* 用函数取代参数
* 移除参数
* 保留完整对象
* 引入参数对象
* 以函数取代参数
* 移除设置函数
* 隐藏函数
* 以测试取代异常
* 封装向下转型
* 以异常取代错误码
* 以工厂函数取代构造函数
* 将查询函数和修改函数分离
处理概括关系
* 字段上移
* 字段下移
* 函数上移
* 抽取子类
* 构造函数本体上移
* 抽取超类
* 函数下移
* 抽取接口
* 折叠继承体系
* 塑造函数模版
* 以委托取代继承
* 以继承取代委托
- 谈谈你对Mvc的认识
MVC是一种设计模式,强制使输入、处理、输出分开,MVC的三个核心部分:M模型,V视图,C控制器。
视图就是用户看到并与之交互的界面。
模型就是程序的数据业务规则。
控制器接收用户的数组调用模型和视图去完成用户需求。
使用MVC的优点:低耦合、高重用性、较低的生命周期成本、快速开发部署、可维护性、可扩展性,有利于软件工程化管理。
MVC的缺点:没有明确的定义,完全理解并不容易。小型项目不适合用MVC。
5、持续集成
- 什么是持续继承?
持续集成指的是,频繁地(一天多次)将代码集成到主干。
(1)快速发现错误。每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易。
(2)防止分支大幅偏离主干。如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。
持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。
- 什么是单元测试?为什么要做单元测试?
经验表明一个尽责的单元测试方法将会在软件开发的某个阶段发现很多的Bug,并且修改它们的成本也很低。在软件开发的后期阶段,Bug的发现并修改将会变得更加困难,并要消耗大量的时间和开发费用。无论什么时候作出修改都要进行完整的回归测试,在生命周期中尽早地对软件产品进行测试将使效率和质量得到最好的保证。在提供了经过测试的单元的情况下,系统集成过程将会大大地简化。开发人员可以将精力集中在单元之间的交互作用和全局的功能实现上,而不是陷入充满很多Bug的单元之中不能自拔。
使测试工作的效力发挥到最大化的关键在于选择正确的测试策略,这其中包含了完全的单元测试的概念,以及对测试过程的良好的管理,还有适当地使用象AdaTEST和Cantata这样的工具来支持测试过程。这些活动可以产生这样的结果:在花费更低的开发费用的情况下得到更稳定的软件。更进一步的好处是简化了维护过程并降低了生命周期的费用。有效的单元测试是推行全局质量文化的一部分,而这种质量文化将会为软件开发者带来无限的商机。
二、笔试题目
1.写出5个以上你所知道的常用的Linux命令和它的功能
cat,显示文件内容。
cd,改变目录路径。
cp,复制文件。
find,查找文件。
grep,搜索、过滤信息。
ls,列出目录信息。
more,分页显示。
rm,删除文件或目录。
vi,调用vi文本编辑器。
who,显示登录用户信息。
2.写出PHP(或其他语言)的public、protected、private三种访问控制模式的区别?
Public可以外部访问
Protected,private只可以内部访问
Public,protected可以被继承
Private不可以被继承
3.请问GET和POST方法有什么区别?
网页上填写的表单信息都可以通过这两个方法将数据传递到服务器上,
当我们使用GET方法是,所有的信息都会出现在URL地址中,并且使用GET方法最多只能传递1024个字符,
所以如果在传输量小或者安全性不那么重要的情况下可以使用GET方法。
POST方法,最多可以传输2MB字节的数据,而且可以根据需要调节。
4.双引号和单引号的区别
双引号解释变量,单引号不解释变量
双引号里插入单引号,其中单引号里如果有变量的话,变量解释
双引号的变量名后面必须要有一个非数字、字母、下划线的特殊字符,或者用{}讲变量括起来,否则会将变量名后面的部分当做一个整体,引起语法错误
双引号解释转义字符,单引号不解释转义字符,但是解释'\和\\
能使单引号字符尽量使用单引号,单引号的效率比双引号要高(因为双引号要先遍历一遍,判断里面有没有变量,然后再进行操作,而单引号则不需要判断)
5.常用的超全局变量(8个)
$_GET ----->get传送方式
$POST ----->post传送方式
$REQUEST ----->可以接收到get和post两种方式的值
$SESSION ----->会话控制的时候会用到
$COOKIE ----->会话控制的时候会用到
$GLOBALS ----->所有的变量都放在里面
$FILE ----->上传文件使用
$SERVER ----->系统环境变量
$ENV ----->系统环境变量
6.请写一个函数验证电子邮件的格式是否正确 ?
function checkEmail($email)
{
$pregEmail = "/([a-z0-9]*[-_\.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\.][a-z]{2,3}([\.][a-z]{2})?/i";
return preg_match($pregEmail,$email);
}
7.求$a 的值
$a = 3;
echo "$a";
echo '$a';
echo "$a";
echo "\$a";
echo "\$a";
echo "${a}";
echo '${a}';
echo "$a"."$a";
echo "$a"+"$a";
$a = 3;
echo "$a"; // 3
echo '$a'; // $a
echo "\$a"; // $a
echo "\\$a"; // \3
echo "\\\$a"; // \$a
echo "${a}"; //3
echo '${a}'; //${a}
echo "$a"."$a"; // 33
echo "$a"+"$a";// 6
8.MySQL 数据库中 varchar和char的主要区别是什么,哪种查询效率更高,为什么?
varchar变长字符串,char定长字符串
Char效率更高,由于不需要对储存空间计算后在存储,所以效率更高
9.使用 PHP 下载网络图片,有哪些方法?
1.file_get_contents
2.readfile读取内容
3.fopen系列函数
4.curl
10.Include 与 require的区别,require和require_once的效率哪个高?
Php在遇到include时就解释一次,如果页面中出现10次include,php就解释10次,而php遇到require时只解释一次,即使页面出现多次require也只解释一次,因此require的执行表率比include高。
Php使用require包含文件时将被包含的文件当成当前文件的一个组成部分,如果被包含的文件中有语法错误或者被包含的文件不存在,则php脚本将不再执行,并提示错误。
Php使用include包含文件时相当于指定了这个文件的路径,当被包含的文件有语法错误或者被包含的文件不存在时给出警告,不影响本身脚本的运行。
Include在包含文件时可以判断文件是否包含,而require则不管任何情况都包含进来。
Require的效率比require_once的效率更高,因为require_once在包含文件时要进行判断文件是否已经被包含。
11.echo intval(0.58*100) 输出的结果是什么?
结果是57
原因就是浮点数精度的问题。
简单的十进制分数如同 0.1 或 0.7 不能在不丢失一点点精度的情况下转换为内部二进制的格式。这就会造成混乱的结果:例如,floor((0.1+0.7)*10) 通常会返回 7 而不是预期中的 8,因为该结果内部的表示其实是类似 7.9999999999…。这和一个事实有关,那就是不可能精确的用有限位数表达某些十进制分数。例如,十进制的 1/3 变成了 0.3333333…。所以永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。如果确实需要更高的精度,应该使用任意精度数学函数或者 gmp 函数
12.Cookie和session的区别,禁止了cookie后session能正常使用吗?session的缺点是什么?session在服务器端是存在哪里的?是共有的还是私有的?
COOKIE保存在客户端,用户通过手段可以进行修改,不安全,单个cookie允许的最大值是3k。而SESSION保存在服务器端,相对比较安全,大小没有限制。禁用了cookie之session不能正常使用。
Session的缺点:保存在服务器端,每次读取都从服务器进行读取,对服务器有资源消耗。
Session保存在服务器端的文件或数据库中,默认保存在文件中,文件路径由php配置文件的session.save_path指定。
Session文件是公有的。
13.写几个魔术方法并说明作用?
__call()当调用不存在的方法时会自动调用的方法
__autoload()在实例化一个尚未被定义的类是会自动调用次方法来加载类文件
__set()当给未定义的变量赋值时会自动调用的方法
__get()当获取未定义变量的值时会自动调用的方法
__construct()构造方法,实例化类时自动调用的方法
__destroy()销毁对象时自动调用的方法
__unset()当对一个未定义变量调用unset()时自动调用的方法
__isset()当对一个未定义变量调用isset()方法时自动调用的方法
__clone()克隆一个对象
__tostring()当输出一个对象时自动调用的方法
14.HTTP有哪些状态码?每种状态码的含义是什么?
常见的HTTP状态码:
200 - 请求成功
301 - 资源(网页等)被永久转义到其他URL
404 - 请求的资源(网页等)不存在
505 - 内部服务器错误
HTTP状态码分类:
1** - 信息,服务器收到的请求,需要请求者继续执行操作
2** - 成功,操作被成功接收并处理
3** - 重定向,需要进一步的操作以完成请求
4** - 客户端错误,请求包含语法错误或者无法完成请求
5** 服务器错误,服务器在处理请求的过程 中发生了错误
15.描述一下大流量高并发量网站的解决方案
首先,确认服务器硬件是否足够支持当前的流量 普通的P4服务器一般最多能支持每天10万独立IP,如果访问量比这个还要大, 那么必须首先配置一台更高性能的专用服务器才能解决问题 ,否则怎么优化都不可能彻底解决性能问题。
其次,优化数据库访问前台实现完全的静态化当然最好,可以完全不用访问数据库,不过对于频繁更新的网站, 静态化往往不能满足某些功能。
缓存技术就是另一个解决方案,就是将动态数据存储到缓存文件中,动态网页直接调用 这些文件,而不必再访问数据库,WordPress和Z-Blog都大 量使用这种缓存技术 如果确实无法避免对数据库的访问,那么可以尝试优化数据库的查询SQL.避免使用 Select * from这样的语句,每次查询只返回自己需要的结果,避免短时间内的大,尽量做到"所查即所得" ,遵循以小表为主,附表为辅,查询条件先索引,先小后大的原则,提高查询效率.量SQL查询。
禁止外部的盗链 外部网站的图片或者文件盗链往往会带来大量的负载压力,因此应该严格限制外部对于自身的图片或者文件盗链,好在目前可以简单地通过refer来控制盗 链,Apache自 己就可以通过配置来禁止盗链,IIS也有一些第三方的ISAPI可以实现同样的功能。当然,伪造refer也可以通过代码来实现盗 链,不过目前蓄意伪造refer盗链的还不多, 可以先不去考虑,或者使用非技术手段来解决,比如在图片上增加水印。
控制大文件的下载。 大文件的下载会占用很大的流量,并且对于非SCSI硬盘来说,大量文件下载会消耗 CPU,使得网站响应能力下降。因此,尽量不要提供超过2M的大文件下载,如果需要提供,建议将大文件放在另外一台服务器上。
使用不同主机分流主要流量 将文件放在不同的主机上,提供不同的镜像供用户下载。比如如果觉得RSS文件占用流量大,那么使用FeedBurner或者FeedSky等服务将RSS 输出放在其他主机上,这样别人访问的流量压力就大多集中在FeedBurner的主机上,RSS就不占用太多资源了。
使用流量分析统计软件 在网站上安装一个流量分析统计软件,可以即时知道哪些地方耗费了大量流量,哪些页面需要再进行优化,因此,解决流量问题还需要进行精确的统计分析才可以。 我推荐使用的流量分析统计软件是Google Analytics(Google分析)。若还有其他的流量分析软件,欢迎共享交流.
其他算法问题
设计一个进制转换的方法(最大16进制)
考察知识点:stack
设计一个检查括号匹配的程序
考察知识点:stack
设计一个计算器(给出一个表达式计算结果)
考察知识点:stack、逆波兰表达式
网友评论