**1、冒泡排序** ``` function maopao($arr) { $len = count($arr); $n = count($arr) - 1; for ($i = 0; $i < $len; $i++) { for ($j = 0; $j < $n; $j++) { if ($arr[$j] > $arr[$j + 1]) { $tmp = $arr[$j]; $arr[$j] = $arr[$j + 1]; $arr[$j + 1] = $tmp; } } } return $arr; } ``` **2、快速排序** ``` function quick_sort($array) { if (count($array) <= 1) return $array; $key = $array[0]; $left_arr = array(); $right_arr = array(); for ($i=1; $i<count($array); $i++){ if ($array[$i] <= $key) $left_arr[] = $array[$i]; else $right_arr[] = $array[$i]; } $left_arr = quick_sort($left_arr); $right_arr = quick_sort($right_arr); return array_merge($left_arr, array($key), $right_arr); } ``` ### 3、请说明 PHP 中传值与传引用的区别,什么时候传值什么时候传引用? 按值传递:函数范围内对值的任何改变在函数外部都会被忽略 按引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改 优缺点:按值传递时,php必须复制值。特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作。按引用传递则不需要复制值,对于性能提高很有好处。(优缺点会考到) ### 4、MySQL数据库中的字段类型varchar和char的主要区别是什么? Varchar是变长,节省存储空间,char是固定长度。查找效率要char型快,因为varchar是非定长,必须先查找长度,然后进行数据的提取,比char定长类型多了一个步骤,所以效率低一些。 ### 5、MySQL数据库的常用存储引擎以及它们的区别? MyISAM:不支持事务,表锁,易产生碎片,要经常优化,读写速度较快,支持全文索引。 InnoDB:支持事务,行锁,有崩溃恢复能力。读写速度比MyISAM慢,5.6之后支持全文索引。 存储引擎是基于表的,而不是数据库 (这道题还能更详细点就详细点) ### 6、对于大流量的网站,采用什么样的方法来解决访问量问题? 首先,确认服务器硬件是否足够支持当前的流量 其次,优化数据库访问。 第三,禁止外部的盗链。 第四,控制大文件的下载。 第五,使用不同主机分流主要流量 第六,使用流量分析统计软件 第七,尽量使用静态页,缓存 ### 7、什么是面向对象?主要特征是什么? 面向对象是程序的一种设计方式,它利于提高程序的重用性,使程序结构更加清晰。主要特征:封装、继承、多态。 ### 8、SESSION 与 COOKIE的区别是什么? SESSION存储在服务器端,COOKIE保存在客户端。Session比较安全,cookie用某些手段可以修改,不安全。Session依赖于cookie进行传递。禁用cookie后,session还可以使用,在存储session的文件中,生成sessionID,通过get传参的方式将sessionID传到要实现session共享的页面,读取sessionID,从而从session中获取数据。 ### 9、对缓存技术的了解 1、缓存技术是将动态内容缓存到文件中,在一定时间内访问动态页面直接调用缓存文件,而不必重新访问数据库。 2、使用memcache可以做缓存。 ### 10、表单中get和post提交方式的区别 get是显式的,数据从url中可以看到,传输的数据量小,安全性低; post是隐式的,传送的数据量较大,安全性较高 ### 11、优化数据库的方法 选取最适用的字段属性,尽可能减少定义字段宽度,尽量把字段设置NOTNULL 使用连接(JOIN)来代替子查询 适用联合(UNION)来代替手动创建的临时表 事务处理 锁定表、优化事务处理 使用外键,优化锁定表 使用索引 优化查询语句 ### 12、语句include和require的区别是什么?语句include和require的区别是什么? require是无条件包含,也就是如果一个流程里加入require,无论条件成立与否都会先执行require,当文件不存在或者无法打开的时候,会提示错误,并且会终止程序执行 include有返回值,而require没有(可能因为如此require的速度比include快),如果被包含的文件不存在的化,那么会提示一个错误,但是程序会继续执行下去 ### 13、redis和memcacahe、mongoDB的区别? 都是非关系型数据库,性能都非常高,但是mongoDB和memcache、redis是不同的两种类型。后两者主要用于数据的缓存,前者主要用在查询和储存大数据方面,是最接近数据库的文档型的非关系数据库。 从数据存储位置上来分,memcache的数据存在内存中,而redis既可以存储在内存中,也可以存储的到磁盘中,达到持久化存储的功能,memcache一旦断电,数据全部丢失,redis可以利用快照和AOF把数据存到磁盘中,当恢复时又从磁盘中读取到内存中,当物理内存使用完毕后,可以把数据写入到磁盘中。 从存储数据的类型上来分,memcache和redis存储的方式都是键值对,只不过redis值的类型比较丰富,有string(字符串),hash(哈希),list(列表),set(集合)zset(有序集合),而memcache主要存储的是字符串。 ### 14、PHP的基本变量类型 四种标量类型:boolean (布尔型)、integer (整型)、float (浮点型, 也称作 double)、string (字符串) 两种复合类型:array (数组)、object (对象) 最后是两种特殊类型:resource(资源)、NULL(NULL) ### 15、静态化如何实现的?伪静态如何实现? 1、 静态化指的是页面静态化,也即生成实实在在的静态文件,也即不需要查询数据库就可以直接从文件中获取数据,指的是真静态。 实现方式主要有两种: 一种是我们在添加信息入库的时候就生成的静态文件,也称为模板替换技术。 一种是用户在访问我们的页面时先判断是否有对应的缓存文件存在,如果存在就读缓存,不存在就读数据库,同时生成缓存文件。 2、伪静态不是真正意义上的静态化,之所以使用伪静态,主要是为了SEO推广,搜索引擎对动态的文件获取难度大,不利于网站的推广。实习原理是基于Apache或Nginx的rewrite机智 主要有两种方式: 一种是直接在配置虚拟机的位置配置伪静态,这个每次修改完成后需要重启web服务器。 另一种采用分布式的,可以在网站的根目录上创建.htaccess的文件,在里面配置相应的重写规则来实现伪静态,这种每次重写时不需要重启web服务器,且结构上比较清晰。 ### 16、Mysql的读写分离? 读写分离的实现原理就是在执行SQL语句的时候,判断到底是读操作还是写操作,把读的操作转向到读服务器上(从服务器,一般是多台),写的操作转到写的服务器上(主服务器,一般是一台,视数据量来看)。当然为了保证多台数据库数据的一致性,需要主从复制。 ### 17、如何处理负载,高并发? 1、HTML静态化 效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的 网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。 2、图片服务器分离 把图片单独存储,尽量减少图片等大流量的开销,可以放在一些相关的平台上,如七牛等 3、数据库集群和库表散列及缓存 数据库的并发连接为100,一台数据库远远不够,可以从读写分离、主从复制,数据库集群方面来着手。另外尽量减少数据库的访问,可以使用缓存数据库如memcache、redis。 4、镜像: 尽量减少下载,可以把不同的请求分发到多个镜像端。 5、负载均衡: Apache的最大并发连接为1500,只能增加服务器,可以从硬件上着手,如F5服务器。当然硬件的成本比较高,我们往往从软件方面着手。 ### 18、说一下单引号双引号? 单引号内部的变量不会执行, 双引号会执行 单引号解析速度比双引号快。 单引号只能解析部分特殊字符,双引号可以解析所有特殊字符。 ### 19、PHP7的新特性? 标量类型声明:PHP 7 中的函数的形参类型声明可以是标量了。在 PHP 5 中只能是类名、接口、array 或者 callable (PHP 5.4,即可以是函数,包括匿名函数),现在也可以使用 string、int、float和 bool 了。 返回值类型声明:增加了对返回类型声明的支持。 类似于参数类型声明,返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。 NULL 合并运算符:由于日常使用中存在大量同时使用三元表达式和 isset()的情况,NULL 合并运算符使得变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。 use 加强:从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了 匿名类:现在支持通过new class 来实例化一个匿名类 ### 20、PHP 数组排序 sort() - 以升序对数组排序 rsort() - 以降序对数组排序 asort() - 根据值,以升序对关联数组进行排序 ksort() - 根据键,以升序对关联数组进行排序 arsort() - 根据值,以降序对关联数组进行排序 krsort() - 根据键,以降序对关联数组进行排序 ### 21、建立索引 ``` (普通索引)-> 创建:CREATE INDEX <索引名> ON tablename (索引字段) 修改:ALTER TABLE tablename ADD INDEX [索引名] (索引字段) 创表指定索引:CREATE TABLE tablename([...],INDEX[索引名](索引字段)) (唯一索引)-> 创建:CREATE UNIQUE <索引名> ON tablename (索引字段 修改:ALTER TABLE tablename ADD UNIQUE [索引名] (索引字段) 创表指定索引:CREATE TABLE tablename([...],UNIQUE[索引名](索引字段)) (主键)-> 它是唯一索引,一般在创建表是建立,格式为: CREATA TABLE tablename ([...],PRIMARY KEY[索引字段]) ``` ### 22、使用过Memcache缓存吗,如果使用过,能够简单的描述一下它的工作原理吗? Memcahce是把所有的数据保存在内存当中,采用hash表的方式,每条数据又key和value组成,每个key是独一无二的,当要访问某个值的时候先按照找到值,然后返回结果。Memcahce采用LRU算法来逐渐把过期数据清除掉。 ### 23,优化MYSQL数据库的方法 ``` (1)选择最有效率的表名顺序 (2)WHERE子句中的连接顺序 (3)SELECT子句中避免使用‘*’ (4)用Where子句替换HAVING子句 (5)通过内部函数提高SQL效率 (6)避免在索引列上使用计算。 (7)提高GROUP BY 语句的效率, 可以通过将不需要的记录在GROUP BY 之前过滤掉。 (8). 选取最适用的字段属性,应该尽量把字段设置为NOT NULL (9). 使用连接(JOIN)来代替子查询(Sub-Queries) (10). 使用联合(UNION)来代替手动创建的临时表 (11).尽量少使用 LIKE 关键字和通配符 (12).使用事务和外键 ``` ### 24、MySQL主从备份的原理? mysql支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。 ### 25、error\_reporting() 的作用? 设置 PHP 的报错级别并返回当前级别。 ### 26、如何修改session的生存时间 在php.ini 中设置 session.gc\_maxlifetime = 1440 //默认时间 代码实现 ``` $lifeTime = 24 * 3600; // 保存一天 session_set_cookie_params($lifeTime); session_start(); ``` ### 27、常见的 PHP 安全性攻击 SQL注入: 用户利用在表单字段输入SQL语句的方式来影响正常的SQL执行。 防止: 使用mysql_real_escape_string()过滤数据 手动检查每一数据是否为正确的数据类型 使用预处理语句并绑定变量 参数化SQL:是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,用@或?来表示参数。 **XSS攻击 **:跨站点脚本攻击,由用户输入一些数据到你的网站,其中包括客户端脚本(通常JavaScript)。如果你没有过滤就输出数据到另一个web页面,这个脚本将被执行。 防止:为了防止XSS攻击,使用PHP的htmlentities()函数过滤再输出到浏览器。 **CSRF**:跨站点请求伪造,是指一个页面发出的请求,看起来就像是网站的信任用户,但是是伪造的 防止:一般来说,确保用户来自你的表单,并且匹配每一个你发送出去的表单。有两点一定要记住: 对用户会话采用适当的安全措施,例如:给每一个会话更新id和用户使用SSL。 生成另一个一次性的令牌并将其嵌入表单,保存在会话中(一个会话变量),在提交时检查它。 如laravel中的 _token 代码注入:代码注入是利用计算机漏洞通过处理无效数据造成的。问题出在,当你不小心执行任意代码,通常通过文件包含。写得很糟糕的代码可以允许一个远程文件包含并执行。如许多PHP函数,如require可以包含URL或文件名。 防止代码注入 过滤用户输入 在php.ini中设置禁用allow_url_fopen和allow_url_include。这将禁用require/include/fopen的远程文件 ### **28、**FILE**表示什么意思?** 文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自PHP4.0.2 起,**FILE**总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。 ### 29、如何获取客户端的IP地址? ~~~bash $_SERVER[‘REMOTE_ADDR’] ~~~ ### 30.写出使用header函数跳转页面的语句 ~~~css Header(‘location:index.php’); ~~~ ### 31, $str是一段html文本,使用正则表达式去除其中的所有js脚本 ~~~bash $pattern = ‘/<script.*>\.+<\/script>/’; Preg_replace($pattern,’’,$str); ~~~ ### 32.写出将一个数组里的空值去掉的语句 ``` $arr = array(‘’,1,2,3,’’,19); 第一种方法: $array1 = array(' ',1,'',2,3); print_r(array_filter($array1, "del")); function del($var) { return(trim($var)); } 第二种方法: $arr=array("",1,2,3,""); $ptn="/\S+/i"; print_r(preg_grep($ptn,$arr)); ``` ### 33.写出获取当前时间戳的函数,及打印前一天的时间的方法(格式:年-月-日 时:分:秒) ~~~css Time(); Date(“Y-m-d H:i:s”,Strtotime(“-1 day”)); ~~~ ### 34.**写出php进行编码转换的函数** ~~~bash Iconv(‘utf-8’,’gb2312’,$str); ~~~ ### 35,**$str = “1,3,5,7,9,10,20”,使用什么函数可以把字符串str转化为包含各个数字的数组?** ~~~bash $arr = explode(“,”,$str); ~~~ ### 36,**serialize() /unserialize()函数的作用** serialize()和unserialize()在 php 手册上的解释是: serialize — 产生一个可存储的值的表示,返回值为字符串,此字符串包含了表示 value 的字节流,不丢失其类型和结构,可以存储于任何地方。 unserialize — 从已存储的表示中创建 PHP 的值 具体用法: ~~~bash $arr = array(“测试1″,”测试2″,”测试3″);//数组 $sarr = serialize($arr);//产生一个可存储的值(用于存储) //用任意方法(例如:你要是吧$sarr存在一个文本文件中你就可以用file_get_contents取得)得到存储的值保存在$newarr中; $unsarr=unserialize($newarr);//从已存储的表示中创建 PHP 的值 ~~~ ### 37,**写出一个函数,参数为年份和月份,输出结果为指定月的天数** ~~~php function day_count($year,$month){ echo date(“t”,strtotime($year.”-”.$month.”-1”)); } ~~~ ### 38,**一个文件的路径为/wwwroot/include/page.class.php,写出获得该文件扩展名的方法** ~~~ruby $arr = pathinfo(“/wwwroot/include/page.class.php”); $str = substr($arr[‘basename’],strrpos($arr[‘basename’],’.’)); ~~~ ### 39,**你使用过哪种PHP的模板引擎?** Smarty,thinkphp自带的模板引擎 ### 40,## i++和++i命令的区别有 i++先做别的事,再自己加1 ++i先自己加1,再做别的事情 ++i比i++效率要高 ### 41, echo、print_r、print、var_dump 1. echo、print是php语句,var_dump和print_r是函数 2. echo 输出一个或多个字符串,中间以逗号隔开,没有返回值是语言结构而不是真正的函数,因此不能作为表达式的一部分使用 3. print也是php的一个关键字,有返回值 只能打印出简单类型变量的值(如int,string),如果字符串显示成功则返回true,否则返回false 4. print\_r 可以打印出复杂类型变量的值(如数组、对象)以列表的形式显示,并以array、object开头,但print\_r输出布尔值和NULL的结果没有意义,因为都是打印”\\n”,因此var\_dump()函数更适合调试 5. var_dump() 判断一个变量的类型和长度,并输出变量的数值 ### 42, php中字符串处理函数 trim 移除空白字符或特定字符 ltrim rtrim expload 数组转化成字符串 substr 字符串截取 substr\_resplace 子字符串替换 strlen 字符串长度 strtolower strtoupper md5 implode strpos在指定字符串中查找目标字符串第一次出现的位置 ### 43,一条SQL语句在MySQL中如何执行的? 客户端请求 —-> 连接器(验证用户身份,给予权限) —-> 查询缓存(存在缓存则直接返回,不存在则执行后续操作) —-> 分析器(对SQL进行词法分析和语法分析操作) —-> 优化器(主要对执行的sql优化选择最优的执行方案方法) —-> 执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口) —-> 去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果) ### 44,PHP-FPM与Nginx的通信机制? 两种方式 1 tcp (ip:端口) 2、unix domain socket ### 45,数组排序 ``` sort() 函数用于对数组单元从低到高进行排序。 rsort() 函数用于对数组单元从高到低进行排序。 asort() 函数用于对数组单元从低到高进行排序并保持索引关系。 arsort() 函数用于对数组单元从高到低进行排序并保持索引关系。 ksort() 函数用于对数组单元按照键名从低到高进行排序。 krsort() 函数用于对数组单元按照键名从高到低进行排序。 ``` ### 46, memcache 和 Redis 的区别 数据结构:memcache仅支持简单的key-value形式,Redis支持的数据更多(string字符串,set集合,list列表,hash散列,zset有序集合); 多线程:memcache支持多线程,Redis支持单线程 持久化:Redis支持持久化,memcache不支持持久化 分布式:Redis做主从结构,memcache服务器需要通过hash一致化来支撑主从结构 ### 47,什么是 Redis 穿透和雪崩 缓存击穿 **缓存穿透**:就是访问redis中一个不存在的key的时候,会直接穿过缓存,去数据库中进行查询. **缓存雪崩**:就是每秒有5000个请求过来时候,redis缓存库崩了,然后这些请求瞬间落在了mysql数据库上,直接导致数据库死机. **缓存击穿**:简单地说就是缓存过期大量线程访问数据库 ### 48,说说对 SQL 语句优化有哪些方法? 不用\*来代替所有列名,尽量采用与访问表相关的实际列名; 尽量减少表的查询次数。 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描 ### 49,Mysql 中有哪几种锁 MyISAM支持表锁,InnoDB支持表锁和行锁,默认为行锁 * 表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低 * 行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高 ### 50,如何处理负载、高并发 * 动静分类 * 添加cdn,同时可以把图片等保存的cos对象储存中 * 使用负载均衡 * 合理添加缓存,最好是以内存为基础的缓存如redis * 添加redis分布式锁 * 前端页面合理设计,避免高速点击的状况出现 * 添加队列来处理高并发 * 使用数据库连接池 * 对数据库及程序优化,分库分表 ### 51,为什么要使用分布式锁 分布式系统要访问共享资源,为了避免并发访问资源带来错误,我们为共享资源添加一把锁,让各个访问互斥,保证并发访问的安全性 ### 52,单线程的redis如何实现阻塞队列 整个阻塞执行过程相当于是分散开的,每次请求结束后都判断之前的阻塞列表是否满足执行条件,类似我们用轮询来实现长连接的功能。所以看似阻塞的命令对其他命令的执行时不会有影响的,它们依然是单线程的。 ### 53,消息中间件 基于队列与消息传递,降低系统耦合,提高系统响应速度,突破系统性能瓶颈。削锋,解耦 ### 54, PHP网络通信是如何实现的 基于socket实现,可以用到现在的swoole,wokerman等 ### 55, 事务的其特性有哪些?mysql是否支持嵌套事务?(默认不支持) 所谓事务就是针对数据库的一组操作,它可以由一条或者多条SQL语句组成,同一个事务的操作具备同步的特点,如果其中有一条语句不能执行的话,那么所有的语句都不会执行 (1)原子性: 原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。 (2)一致性:一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。 (3)隔离性:隔离性是指并发的事务是相互隔离的。即一个事务内部的操作及正在操作的数据必须封锁起来,不被企图进行修改的事务看到 。 (4)持久性:持久性是指在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。 即使出现了任何事故比如断电等,事务一旦提交,则持久化保存在数据库中 ## 56, $this和self、parent这三个关键词分别代表什么?在哪些场合下使用? $this:当前对象 self: 当前类 parent: 当前类的父类 $this在当前类中使用,使用->调用属性和方法。 self也在当前类中使用,不过需要使用::调用。 静态属性,不能在类里使用$this访问,应该使用self后跟范围解析操作符(::),后面是带着美元符号的变量名。 ## 57,PHP的性能优化方法总结 * 多用PHP自身能力解决问题 * 多使用PHP内置的变量、常量、函数 * 少用PHP魔术方法 * 利用unset()及时释放不使用的内存 * 做PHP擅长的事情 * 尽量静态化 * 尽量的少进行文件操作,虽然PHP的文件操作效率也不低的 * 其他自行挖掘 ## 58,安全对一套程序来说至关重要,请说说在开发中应该注意哪些安全机制? 1. 防远程提交 2. 防止SQL注入,对特殊代码进行过滤 3. 防止注册灌水,使用验证码 4. 数据加密处理等等 ## 59, TCP长连接与短连接的区别,各自的优点与缺点,以及其使用场景 * 长连接的操作步骤是:建立连接->数据传输…(保持连接)…数据传输->关闭连接。 * 短连接的步骤是:建立连接->数据传输->关闭连接…建立连接->数据传输->关闭连接。 * 长链接做聊天室类似场景,短链接做网站场景 ## 60, localhost与127.0.01的区别 * localhot(local)是不经网卡传输!这点很重要,它不受网络防火墙和网卡相关的的限制。 * 127.0.0.1是通过网卡传输,依赖网卡,并受到网络防火墙和网卡相关的限制。 * 一般设置程序时本地服务用localhost是最好的,localhost不会解析成ip,也不会占用网卡、网络资源 ## 61, Select Count (\*)和Select Count(1)以及Select Count(column)区别 * 一般情况下,Select Count (\*)和Select Count(1)两者的返回结果是一样的 * 假如表沒有主键(PK), 那么count(1)比count(*)快, 如果有主键PK的話,那count(主键)最快, 如果你的表只有一个字段的话那count(*)就是最快的 * count(\*) 跟 count(1) 的结果一样,都包括对NULL的统计,而count(column) 是不包括NULL的统计 * count(column) 是表示结果集中有多少个column字段不为空的记录 * ## 62,列关于PHP中大小写说法正确的是 ``` 1. 内置的结构以及关键字、用户定义的类和函数是不区分大小写 2. 变量名严格区分大小写 3. 常量名可以通过define()进行设置是否对大小写敏感,详细内容见下图: 4. 魔术常量是不区分大小写的 ``` ## 63,git cvs svn CVS及SVN都是集中式的版本控制系统,而Git是分布式版本控制系统 Git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针 ## 64, mysql索引不会命中的情况 * 如果条件中有 or ,即使其中有条件带索引也不会命中(这也是为什么尽量少用or的原因) 注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引如果出现OR的一个条件没有索引时,建议使用 union ,拼接多个查询语句 * like查询是以%开头,如果是int型索引不会命中,字符型的命中’test%’百分号只有在右边才可以命中 * 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引 * 没有查询条件,或者查询条件没有建立索引 * 查询条件中,在索引列上使用函数(+, - ,\*,/), 这种情况下需建立函数索引 * 采用 not in, not exist * B-tree 索引 is null 不会走, is not null 会走 * 联合索引遵循最左原则,不满足的不会命中 * 链表时,如果关联字段的的编码不同,也不会走索引。如一个表时 utf8,另外一个表是utf8mb4 ## 65,varchar char 1. Varchar 对每个英文(ASCII)字符都占用2个字节,对一个汉字也只占用两个字节 2. char 对英文(ASCII)字符占用1个字节,对一个汉字占用2个字节 ## 66,$\_REQUEST 默认情况下包含了 $_GET, $_POST 和 $_COOKIE 的数组 ## 67,psr规范 此处的“类”泛指所有的class类、接口、traits可复用代码块以及其他类似结构。 一个完整的类名需要具有以下结构 ()\* 1.完整的类名必须要有一个顶级命名空间,被称为“Vendor namespace” 2.完成的类名可以有一个或多个子命名空间 3.完整的类名必须有一个最终的类名 4.完整的类名中任意一部分中的下划线都是没有特殊意义的 5.完整的类名可以由任意大小写字母组成 6.所有类名都必须是大小写敏感的 当根据完整的类名载入相应的文件…… 1.完整的类名中,去掉最前面的命名空间分隔符,前面连续的一个或多个命名空间和子命名空间,作为“命名空间前缀”,其必须与至少一个“文件基目录”相对应。 2.紧接命名空间前缀后的子命名空间必须与相对应的“文件基目录”相匹配,其中的命名空间分隔符作为目录分割符 3.末尾的类名必须与对应的.php为后缀的文件同名 4.自动加载器(autoloader)的实现一定不能抛出异常,一定不能触发任一级别的错误信息以及不应该有返回值。 ## 68,Redis支持五种数据类型: 1. string(字符串), 2. hash(哈希), 3. list(列表), 4. set(集合)及 5. zset(sorted set:有序集合)。 ### **69.详述一次完整的HTTP请求过程** 这个问题的核心是域名解析和服务器(nginx)解析这两部分,基本上这两部分详细阐述就可以了。 步骤一、解析URL 浏览器会解析当前的URL数据,判断此URL是否为合法的链接。如果是合法链接则正常的向下一步骤前进。如果不是合法的链接,则会执行搜索功能,例如执行百度、360、Google搜索等。 步骤二、解析域名 服务器是以ip的形式存在的。而域名需要解析到ip上,解析IP会有三个小的步骤: 1)、从浏览器自身的缓存中解析此域名数据 2)、从本地电脑的HOST文件中解析域名 3)、通过DNS服务器解析域名 步骤三、拿信息 这个步骤我们拿到了URL的信息,主要是IP和端口信息。 步骤四、封包并进行三次握手 浏览器将请求信息进行打包,通过TCP的三次握手将数据传递至服务器。 步骤五、服务器解析、处理、返回数据 服务器通过种种层级、方式拿到传递的数据,对数据进行分析、处理,最后返回响应类MIME类型数据。正常状态码为200,非正常的错误码有404、500、501等等 步骤六、浏览器获得、渲染、展现数据 ### **70, HTTP 状态中302、403、 500代码含义?** 一. 消息系列 二 成功系列 三. 重定向系列 四. 请求错误系列 五. 服务器端错误系列 302:临时转移成功,请求的内容已转移到新位置 403:禁止访问 500:服务器内部错误 401代表未授权。 ### **71,Linux 下建立压缩包,解压缩包的命令** Tar.gz: 打包: tar czf file.tar.gz file.txt 解压: tar xzf file.tar.gz Bz2: 打包: bzip2 [-k] 文件 解压: bunzip2 [-k] 文件 Gzip(只对文件,不保留原文件) 打包: gzip file1.txt 解压: gunzip file1.txt.gz Zip: -r 对目录 打包: zip file1.zip file1.txt 解压: unzip file1.zip ### 72, **不使用cookie向客户端发送一个cookie.** 理解:session_start()开启时,生成一个常量 SID,当COOKIE开启时,这个常量为空,当COOKIE关闭时,这个常量中存储了PHPSESSID的值。通过在URL后加一个SID参数来传递SESSIONID的值,从而使客户端页面可以使用SESSION里面的值。 当客户端开启COOKIE和服务器端开启SESSION时。 浏览器第一次请求,服务器会向浏览器端发送一个COOKIE里面存储SESSIONID. 当浏览器第二次请求时,会把已存在 ### 73,**isset() 和 empty() 区别** Isset判断变量是否存在,可以传入多个变量,若其中一个变量不存在则返回假,empty判断变量是否为空为假,只可传一个变量,如果为空为假则返回真。 ### 74, **持久化redis有几种方式?** 主要有两种方式: 1) 快照持久化 在redis配置文件中已经自动开启了, 格式是:save N M 表示在N秒之内,redis至少发生M次修改则redis抓快照到磁盘。 当然我们也可以手动执行save或者bgsave(异步)命令来做快照 2)append only file AOF持久化 总共有三种模式,如 appendfsync everysec默认的是每秒强制写入磁盘一次 appendfsync always 每次执行写操作的时候就强制写入磁盘 appendfsync no 完全取决于os,性能最好但是持久化没法保证 其中第三种模式最好。redis默认的也是采取第三种模式。 ### 75,**sql注入是什么及如何预防sql注入?** SQL注入攻击指的是用户或者黑客通过构建特殊的输入作为参数传入我们的Web应用程序端,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序员没有细致地过滤用户输入的数据,致使非法数据侵入系统而造成的。因此我们在做开发过程中一定要预防sql注入,主要从两方面着手: 1)占位符的方式,就是对sql语句进行预处理,然后执行sql语句 2)通过addslashes或者mysql_real_escape_string这两个函数对用户输入的值进行转义处理,把一些特殊的字符转义掉。 ### 76,**有用过预处理么?** PDO类中,有个prepare方法可以实现预处理,PDOStament类中 的excute方法可以执行预处理,预处理的参数分为两种,一种是:字符串占位符,另一种是?占位符,:字符串占位符在执行预处理传递参数时传入的是关联数组,而?占位符传递的是索引数组。两者不能混合使用,但一般推荐使用:字符串占位符。 ### 77,**用框架还用自己的处理吗** 一般成熟的开源框架中都考虑到了数据安全这方面的东西,但有时候我们可能会使用一些原生的SQL语句时,我们就需要考虑自己对sql语句进行预处理。当然有时候框架中的过滤方法我们不希望采用,比如使用文本编辑器时,我们可以使用自己的过滤方式 ### 78,**mysql优化怎么做的?** mysql优化主要从以下几个方面来实现: 1)设计角度:存储引擎的选择,字段类型选择,范式 2)功能角度:可以利用mysql自身的特性,如索引,查询缓存,碎片整理,分区、分表等 3)sql语句的优化方面:尽量简化查询语句,能查询字段少就尽量少查询字段,优化分页语句、分组语句等。 4)部署大负载架构体系:数据库服务器单独出来,负载大时可以采用主从复制,读写分离机制进行设计 5)从硬件上升级数据库服务器。 ### 79,**PHP处理上传文件信息数组中的文件类型$\_FILES\[‘type’\]由客户端浏览器提供,有可能是黑客伪造的信息,请写一个函数来确保用户上传的图像文件类型真实可靠** 用getimagesize来判断上传图片的类型比$_FILES函数的type更可靠 同一个文件,使用不同的浏览器php返回的type类型是不一样的,由浏览器提供type类型的话, 就有可能被黑客利用向服务器提交一个伪装撑图片后缀的可执行文件。 可以通过getimagesize()函数来判断上传的文件类型,如果是头像文件 会返回这样的一个数组 ### 80,**PHP的垃圾收集机制是怎样的?** 说明: 1)如果,你熟悉PHP源码,那么请从源码入手,回答些问题,会获得额外加分 2)如果,你不熟悉PHP源码,那么尽你所能,多写点东西,包括利用自己的编程直觉得到的信息,都可以。 3)对,则有分,错误不扣,不写无分。 PHP可以自动进行内存管理,清除不再需要的对象。PHP使用了引用计数(referencecounting)这种单纯的垃圾回收(garbagecollection)机制。每个对象都内含一个引用计数器,每个reference连接到对象,计数器加1。当reference离开生存空间或被设为NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将不再需要使用这个对象,释放其所占的内存空间。 ### 81, **微信支付回调失败该如何处理?** 他问的是已经支付成功后,但是回调失败了。 自己可以创建定时任务在每天的凌晨执行,去微信那边对账,然后更新数据库订单状态。 ### 82, **调用区块链接口的安全措施,有那些实现方法?** 1.使用MD5实现对接口加签,目的是为了防止篡改数据。 2.基于网关实现黑明单与白名单拦截 3.可以使用rsa非对称加密 公钥和私钥互换 4.如果是开放接口的话,可以采用oath2.0协议 5.使用Https协议加密传输,但是传输速度慢 6.对一些特殊字符实现过滤 防止xss、sql注入的攻击 7.定期使用第三方安全扫描插件 8.接口采用dto、do实现参数转化 ,达到敏感信息脱敏效果 9.使用token+图形验证码方法实现防止模拟请求 10.使用对ip访问实现接口的限流,对短时间内同一个请求(ip)一直访问接口 进行限制。 ### 83, **服务器受到dos攻击,这个问题如何应付?** 看看你的服务的访问日志,在防火墙中加过滤,或者在web服务器中加过滤吧。方法有以下几种。 对于特定的IP访问的情况,限制IP访问 限制同一IP在单位时间内的访问次数 上级服务器,提高吞吐能力 是消耗服务器资源为主还是纯流量攻击?消耗资源的可以通过配置防火墙过滤规则防御中小规模的攻击。如果是纯流量攻击,考虑你用的是linode真心无解。即便你封了IP封了端口也没用,人家不管你接不接受他的请求,他都会塞满你的带宽。linode必然认为你是被流量攻击或者消耗过多资源然后给你挂起。 ### 84,**对于大流量的网站,您采用什么样的方法来解决访问量问题?** 优化程序,优化数据库,如果程序和数据库已经最优化,使用以下解决方法: 1.确定当前服务器设备是否满足流量需求。 2.使用Memcache缓存技术,把动态内容缓存到文件中,动态网页直接调用这些文件,而不必再访问数据库。 3.禁止外部盗链,图片和文件外部盗链会给服务器带来大量的负载压力,可以通过refer来禁止外部盗链,或者使用apache来配置禁止盗链。 4.控制大文件的下载,大文件的下载对于非SCSI硬盘来说会占用大量的资源,导致服务器的响应能力下降。 5.使用不同的主机分流主要流量,使服务器均衡负载。 6.使用流量统计软件统计分析网站流量,可以知道哪些地方耗费了大量的流量,哪些页面需要再进行优化。 ### 85, **.对关系型数据库而言,索引是相当重要的概念,请回答有关索引几个问题:** 1)索引的目的是什么? 快速访问数据表中的特定信息,提高检索速度 创建唯一性索引,保证数据库表中每一行数据的唯一性 加速表和表之间的连接 使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间 2) 索引对数据库系统的负面影响是什么? 负面影响:创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;当对表进行增、删、改的时候索引也要动态维护,这样就降低了数据的维护速度。 3) 为数据表建立索引的原则有哪些? 在最频繁使用的、用以缩小查询范围的字段上建立索引 在平频繁使用的、需要排序的字段上建立索引 4) 什么情况下不宜建立索引? 对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引 对于一些特殊的数据类型,不宜建立索引,比如文本字段(text),值范围较少的知道等。 ### 86,AJAX的优势是什么? ajax是异步传输技术,可以通过javascript实现,也可以通过JQuery框架实现,实现局部刷新,减轻了服务器的压力,也提高了用户体验 ### 87,安全对一套程序来说至关重要,请说说在开发中应该注意哪些安全机制? ①防远程提交;②防SQL注入,对特殊代码进行过滤;③防止注册机灌水,使用验证码; ### 88,在程序的开发中,如何提高程序的运行效率? ①优化SQL语句,查询语句中尽量不使用select *,用哪个字段查哪个字段;少用子查询可用表连接代替;少用模糊查询;②数据表中创建索引;③对程序中经常用到的数据生成缓存; ### 89,PHP可否与其它的数据库搭配使用? PHP与MYSQL数据库是最优搭配,当然PHP也可以去其它的数据库搭配使用,例如MSSQL等,PHP中预留了操作MSSQL的函数,只要开启就可以使用 ### 90,现在编程中经常采取MVC三层结构,请问MVC分别指哪三层,有什么优点? MVC三层分别指:业务模型、视图、控制器,由控制器层调用模型处理数据,然后将数据映射到视图层进行显示,优点是:①可以实现代码的重用性,避免产生代码冗余;②M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式 ### 91,对json数据格式的理解? `JSON(JavaScript Object Notation)`是一种轻量级的数据交换格式,json数据格式固定,可以被多种语言用作数据的传递 PHP中处理json格式的函数为`json_decode( string $json [, bool $assoc ] )`,接受一个 JSON格式的字符串并且把它转换为PHP变量,参数json待解码的json string格式的字符串。assoc当该参数为TRUE时,将返回array而非object; `Json_encode`:将PHP变量转换成json格式 ### 92,Print、echo、print\_r有什么区别? ① echo和print都可以做输出,不同的是,echo不是函数,没有返回值,而print是一个函数有返回值,所以相对而言如果只是输出echo会更快,而print\_r通常用于打印变量的相关信息,通常在调试中使用。 ② print 是打印字符串 ③ print\_r 则是打印复合类型 如数组 对象 ### 93,PHP处理时间的常用函数? `date_default_timezone_get()`返回默认时区。 `date_default_timezone_set()`设置默认时区。 `date()`格式化本地时间/日期。 `getdate()`返回日期/时间信息。 `gettimeofday()`返回当前时间信息。 `microtime()`返回当前时间的微秒数。 `mktime()`返回一个日期的 Unix时间戳。 `strtotime()`将任何英文文本的日期或时间描述解析为 Unix时间戳。 `time()`返回当前时间的 Unix时间戳。 ---------------------------------mysql----------------------------------------------- ### 94,SQL语言包括哪几部分?每部分都有哪些操作关键字? SQL语言包括数据定义(DDL)、数据操纵(DML),数据控制(DCL)和数据查询(DQL)四个部分。 数据定义:Create Table,Alter Table,Drop Table, Craete/Drop Index等 数据操纵:Select ,insert,update,delete, 数据控制:grant,revoke 数据查询:select ### 95,完整性约束包括哪些? 数据完整性(Data Integrity)是指数据的精确(Accuracy)和可靠性(Reliability)。 分为以下四类: 1) 实体完整性:规定表的每一行在表中是惟一的实体。 2) 域完整性:是指表中的列必须满足某种特定的数据类型约束,其中约束又包括取值范围、精度等规定。 3) 参照完整性:是指两个表的主关键字和外关键字的数据应一致,保证了表之间的数据的一致性,防止了数据丢失或无意义的数据在数据库中扩散。 4) 用户定义的完整性:不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件。用户定义的完整性即是针对某个特定关系数据库的约束条件,它反映某一具体应用必须满足的语义要求。 与表有关的约束:包括列约束`(NOT NULL(非空约束))`和表约束`(PRIMARY KEY、foreign key、check、UNIQUE)`。 ### 96,什么是事务?及其特性? 事务:是一系列的数据库操作,是数据库应用的基本逻辑单位。 事务特性: (1)原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。 (2)一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态 (3)隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务, (4) 持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。 或者这样理解: 事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。 ### 97, 什么是锁? 数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。 加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。 基本锁类型:锁包括行级锁和表级锁 ### 98 ,什么叫视图?游标是什么? 视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,视图通常是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询。 游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要 ### 99,什么是存储过程?用什么来调用? 存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。可以用一个命令对象来调用存储过程 ### 100,如何通俗地理解三个范式? 第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解; 第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性; 第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。 ### 101, 什么是基本表?什么是视图? 基本表是本身独立存在的表,在 SQL 中一个关系就对应一个表。 视图是从一个或几个基本表导出的表。视图本身不独立存储在数据库中,是一个虚表 ### 102,试述视图的优点? (1) 视图能够简化用户的操作 (2) 视图使用户能以多种角度看待同一数据; (3) 视图为数据库提供了一定程度的逻辑独立性; (4) 视图能够对机密数据提供安全保护。 ### 103,NULL是什么意思 NULL这个值表示UNKNOWN(未知):它不表示“”(空字符串)。 对NULL这个值的任何比较都会生产一个NULL值。您不能把任何值与一个 NULL值进行比较,并在逻辑上希望获得一个答案。 使用IS NULL来进行NULL判断 ### 104,主键、外键和索引的区别? 主键、外键和索引的区别 定义: 主键–唯一标识一条记录,不能有重复的,不允许为空 外键–表的外键是另一表的主键, 外键可以有重复的, 可以是空值 索引–该字段没有重复值,但可以有一个空值 作用: 主键–用来保证数据完整性 外键–用来和其他表建立联系用的 索引–是提高查询排序的速度 个数: 主键–主键只能有一个 外键–一个表可以有多个外键 索引–一个表可以有多个唯一索引 ### 105,你可以用什么来确保表格里的字段只接受特定范围里的值? Check限制,它在数据库表格里被定义,用来限制输入该列的值。 触发器也可以被用来限制数据库表格里的字段能够接受的值,但是这种办法要求触发器在表格里被定义,这可能会在某些情况下影响到性能。 ### 106,说说对SQL语句优化有哪些方法? (1)Where子句中:where表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING最后。 (2)用EXISTS替代IN、用NOT EXISTS替代NOT IN。 (3) 避免在索引列上使用计算 (4)避免在索引列上使用IS NULL和IS NOT NULL (5)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 (6)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描 (7)应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描 ### 107,SQL语句中‘相关子查询’与‘非相关子查询’有什么区别? 子查询:嵌套在其他查询中的查询称之。 子查询又称内部,而包含子查询的语句称之外部查询(又称主查询)。 所有的子查询可以分为两类,即相关子查询和非相关子查询 (1)非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。 (2)相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。 故非相关子查询比相关子查询效率高 ### 108,数据表类型有哪些 MyISAM、InnoDB、HEAP、BOB,ARCHIVE,CSV等。 MyISAM:成熟、稳定、易于管理,快速读取。一些功能不支持(事务等),表级锁。 InnoDB:支持事务、外键等特性、数据行锁定。空间占用大,不支持全文索引等。 ### 109,MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化? a. 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。 b. 选择合适的表字段数据类型和存储引擎,适当的添加索引。 c. mysql库主从读写分离。 d. 找规律分表,减少单表中的数据量提高查询速度。 e.添加缓存机制,比如memcached,apc等。 f. 不经常改动的页面,生成静态页面。 g. 书写高效率的SQL。 ### 110,对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题? a. 确认服务器是否能支撑当前访问量。 b. 优化数据库访问。 c. 禁止外部访问链接(盗链), 比如图片盗链。 d. 控制文件下载。 e. 使用不同主机分流。 f. 使用浏览统计软件,了解访问量,有针对性的进行优化。 ----------------------- 面向对象部分------------------------------- ### 111,简述 private、 protected、 public修饰符的访问权限。 private : 私有成员, 在类的内部才可以访问。 protected : 保护成员,该类内部和继承类中可以访问。 public : 公共成员,完全公开,没有访问限制。 ### 112,堆和栈的区别? 栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义; 堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。 ### 113,XML 与 HTML 的主要区别 (1) XML是区分大小写字母的,HTML不区分。 (2) 在HTML中,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略 或者 之类的结束 标记。在XML中,绝对不能省略掉结束标记。 (3) 在XML中,拥有单个标记而没有匹配的结束标记的元素必须用一个 / 字符作为结尾。这样分析器就知道不用 查找结束标记了。 (4) 在XML中,属性值必须分装在引号中。在HTML中,引号是可用可不用的。 (5) 在HTML中,可以拥有不带值的属性名。在XML中,所有的属性都必须带有相应的值。 ### 114,面向对象的特征有哪些方面? 主要有封装,继承,多态。如果是4个方面则加上:抽象。 下面的解释为理解: 封装: 封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的高内聚,低耦合,防止程序相互依赖性而带来的变动影响. 继承: 在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。 多态: 多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。 抽象: 抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。 ### 115,抽象类和接口的概念以及区别? 抽象类:它是一种特殊的,不能被实例化的类,只能作为其他类的父类使用。使用abstract关键字声明。 它是一种特殊的抽象类,也是一个特殊的类,使用interface声明。 (1)抽象类的操作通过继承关键字extends实现,而接口的使用是通过implements关键字来实现。 (2)抽象类中有数据成员,可以实现数据的封装,但是接口没有数据成员。 (3)抽象类中可以有构造方法,但是接口没有构造方法。 (4)抽象类的方法可以通过private、protected、public关键字修饰(抽象方法不能是private),而接口中的方法只能使用public关键字修饰。 (5)一个类只能继承于一个抽象类,而一个类可以同时实现多个接口。 (6)抽象类中可以有成员方法的实现代码,而接口中不可以有成员方法的实现代码。 ### 116,什么是构造函数,什么是析构函数,作用是什么? 构造函数(方法)是对象创建完成后第一个被对象自动调用的方法。它存在于每个声明的类中,是一个特殊的成员方法。作用是执行一些初始化的任务。Php中使用`__construct()`声明构造方法,并且只能声明一个。 析构函数(方法)作用和构造方法正好相反,是对象被销毁之前最后一个被对象自动调用的方法。是PHP5中新添加的内容作用是用于实现在销毁一个对象之前执行一些特定的操作,诸如关闭文件和释放内存等。 ### 117,如何重载父类的方法,举例说明 重载,即覆盖父类的方法,也就是使用子类中的方法替换从父类中继承的方法,也叫方法的重写。 覆盖父类方法的关键是在子类中创建于父类中相同的方法包括方法的名称、参数和返回值类型。PHP中只要求方法的名称相同即可。 ### 118,常用的魔术方法有哪些?举例说明 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复制一个对象时候调用。 ### 119,类中如何定义常量、如何类中调用常量、如何在类外调用常量 类中的常量也就是成员常量,常量就是不会改变的量,是一个恒值。 定义常量使用关键字const. 例如:`const PI = 3.1415326;` 无论是类内还是类外,常量的访问和变量是不一样的,常量不需要实例化对象, 访问常量的格式都是类名加作用域操作符号(双冒号)来调用。 即:类名 :: 类常量名; ### 120,作用域操作符::如何使用?都在哪些场合下使用? 调用类常量 调用静态方法 ### 121,__autoload()方法的工作原理是什么? 使用这个魔术函数的基本条件是类文件的文件名要和类的名字保持一致。 当程序执行到实例化某个类的时候,如果在实例化前没有引入这个类文件,那么就自动执行\_\_autoload()函数。 这个函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后 就执行include或者require来载入该类,然后程序继续执行,如果这个路径下不存在该文件时就提示错误。 使用自动载入的魔术函数可以不必要写很多个include或者require函数。 ------------------------ThinkPHP部分 ---------------------- ### 122,如何理解TP中的单一入口文件? ThinkPHP采用单一入口模式进行项目部署和访问,无论完成什么功能,一个项目都有一个统一(但不一定是唯一)的入口。应该说,所有项目都是从入口文件开始的,并且所有的项目的入口文件是类似的,入口文件中主要包括: 定义框架路径、项目路径和项目名称(可选) 定义调试模式和运行模式的相关常量(可选) 载入框架入口文件(必须) ### 123,ThinkPHP中的MVC分层是什么? MVC 是一种将应用程序的逻辑层和表现层进行分离的方法。ThinkPHP 也是基于MVC设计模式的。MVC只是一个抽象的概念,并没有特别明确的规定,ThinkPHP中的MVC分层大致体现在: 模型(M):模型的定义由Model类来完成。 控制器(C):应用控制器(核心控制器App类)和Action控制器都承担了控制器的角色,Action控制器完成业务过程控制,而应用控制器负责调度控制。 视图(V):由View类和模板文件组成,模板做到了100%分离,可以独立预览和制作。 但实际上,ThinkPHP并不依赖M或者V ,也就是说没有模型或者视图也一样可以工作。甚至也不依赖C,这是因为ThinkPHP在Action之上还有一个总控制器,即App控制器,负责应用的总调度。在没有C的情况下,必然存在视图V,否则就不再是一个完整的应用。 总而言之,ThinkPHP的MVC模式只是提供了一种敏捷开发的手段,而不是拘泥于MVC本身。 ### 124,如何进行SQL优化? 1)选择正确的存储引擎 以 MySQL为例,包括有两个存储引擎 MyISAM 和 InnoDB,每个引擎都有利有弊。 MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于`SELECT COUNT(*)`这类的计算是超快无比的。 InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。但是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。 (2)优化字段的数据类型 记住一个原则,越小的列会越快。如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多。当然,你也需要留够足够的扩展空间。 (3)为搜索字段添加索引 索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你总要会经常用来做搜索,那么最好是为其建立索引,除非你要搜索的字段是大的文本字段,那应该建立全文索引。 (4)避免使用Select \*从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。即使你要查询数据表的所有字段,也尽量不要用\*通配符,善用内置提供的字段排除定义也许能给带来更多的便利。 (5)使用 ENUM 而不是 VARCHAR ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。例如,性别、民族、部门和状态之类的这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。 (6)尽可能的使用 NOT NULL 除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。 NULL其实需要额外的空间,并且,在你进行比较的时候,你的程序会更复杂。 当然,这里并不是说你就不能使用NULL了,现实情况是很复杂的,依然会有些情况下,你需要使用NULL值。 (7)固定长度的表会更快 如果表中的所有字段都是“固定长度”的,整个表会被认为是 “static” 或 “fixed-length”。 例如,表中没有如下类型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了,这样,MySQL 引擎会用另一种方法来处理。 固定长度的表会提高性能,因为MySQL搜寻得会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量的,所以读取的自然也会很快。而如果字段不是定长的,那么,每一次要找下一条的话,需要程序找到主键。 并且,固定长度的表也更容易被缓存和重建。不过,唯一的副作用是,固定长度的字段会浪费一些空间,因为定长的字段无论你用不用,他都是要分配那么多的空间。 ### 125,什么是惯例配置? 惯例配置上一页下一页惯例重于配置是系统遵循的一个重要思想,系统内置有一个惯例配置文件(位于系统目录下面的Conf\\convention.php),按照大多数的使用对常用参数进行了默认配置。所以,对应用项目的配置文件,往往只需要配置和惯例配置不同的或者新增的配置参数,如果你完全采用默认配置,甚至可以不需要定义任何配置文件。 惯例配置文件会被系统自动加载,无需在项目中进行加载。 ### 126,什么是SQL注入? SQL注入攻击是黑客对数据库进行攻击的常用手段之一。一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,注入者可以在表单中输入一段数据库查询代码并提交,程序将提交的信息拼凑生成一个完整sql语句,服务器被欺骗而执行该条恶意的SQL命令。注入者根据程序返回的结果,成功获取一些敏感数据,甚至控制整个服务器,这就是SQL注入。 ### 127,ThinkPHP如何防止SQL注入? 1)查询条件尽量使用数组方式,这是更为安全的方式; (2)如果不得已必须使用字符串查询条件,使用预处理机制; (3)开启数据字段类型验证,可以对数值数据类型做强制转换; (4)使用自动验证和自动完成机制进行针对应用的自定义过滤; (5)使用字段类型检查、自动验证和自动完成机制等避免恶意数据的输入。 ### 128,TP中支持哪些配置模式?优先级? ThinkPHP在项目配置上面创造了自己独有的分层配置模式,其配置层次体现在: 惯例配置->项目配置->调试配置->分组配置->扩展配置->动态配置 以上是配置文件的加载顺序,因为后面的配置会覆盖之前的同名配置(在没有生效的前提下),所以优先顺序从右到左。 ### 129,TP中的URL模式有哪几种?默认是哪种? ThinkPHP支持四种URL模式,可以通过设置URL\_MODEL参数来定义,包括普通模式、PATHINFO、REWRITE和兼容模式。 默认模式为:PATHINFO模式,设置URL_MODEL 为1 ### 130,TP中系统变量有哪些?如何获取系统变量? 获取系统变量的方法: 只需要在Action中调用下面方法: $this->方法名(“变量名”,\[“过滤方法”\],\[“默认值”\]) ### -----------------------smarty模板引擎---------------------- ### 131,编译和缓存区别? smarty的编译过程就是把模板拿过来,把里面的标签替换成相应php代码,这就是smarty的编译, 其实就是php和html混合的过程 smarty的缓存需要手动开启,smarty的缓存就是把编译好的文件执行后,同时生成一份静态的html页面,再次访问的时候,你访问的就是是html文件了,所以就效率来说,要高一些 ### 132,什么是smarty? Smarty的优点是什么? Smarty是一个使用PHP写出来的PHP模板引擎,目的是要使用PHP程序同美工分离,使的程序员改变程序的逻辑内容时不会影响到美工的页面设计,美工重新修改页面时不会影响到程序的程序逻辑,这在多人合作的项目中显的尤为重要。(也易于程序的多样式开发) Smarty优点 1\. 速度快:相对其他模板引擎。 2\. 编译型:采用smarty编写的程序在运行时要编译成一个非模板技术的PHP文件 3\. 缓存技术:它可以将用户最终看到的HTML文件缓存成一个静态的HTML页 4\. 插件技术:smarty可以自定义插件。 不适合使用smarty的地方 1\. 需要实时更新的内容。例如像股票显示,它需要经常对数据进行更新 2\. 小项目。小项目因为项目简单而美工与程序员兼于一人的项目 ### 133,php查询mysql数据库时,查询中文结果时出现的乱码。怎么解决? 1\. 文件属性(另存为) 2.文件meta(设置浏览器解析的时候) 3\. 连接数据库时编码设定 4\. PHP文件中使用header函数确定编码 ### 134,缓存机制 如果开启了缓存,smarty同时生成一份静态的html页面,如果在设定的时间没有过期,再次访问的时候,你访问的就是是html文件了,减少了读取数据库,所以就效率来说,要高一些。 ### 135,marty模板技术的用途是什么? 为了php与html分开,美工和程序员各司其职,互不干扰 ### 136,smarty配置主要有哪几项? 1\. 引入smarty.class.php; 2\. 实例化smarty对象; 3\. 重新修改默认的模板路径; 4\. 重新修改默认的编译后文件的路径; 5\. 重新修改默认的配置文件的路径; 6\. 重新修改默认的cache的路径。 7\. 可以设置是否开启cache。 8\. 可以设置左侧和右侧定界符。 ### 137,smarty在使用过程中需要注意哪些细节? Smarty是基于MVC概念的一种模板引擎,它将一个页面程序分成了两部分来实现:即视图层和控制层, 也就是说smarty技术将用户UI与php代码分离开。 这样程序员和美工各司其职,互不干扰。 ### 138,smarty运用过程中要注意以下几个问题: 1.正确配置smarty。主要要实例化smarty对象,配置smarty模板文件的路径; 2.php页面中使用assign赋值 和display显示页面; 3.smarty模板文件中不允许出现php代码段,所有的注释,变量,函数都要包含在定界符内。 A.{} B. foreach C. if else D. include E. Literal ### 139, MySQL表锁了如何解锁 1、查进程,查找被锁表的那个进程的ID show processlist; 2、kill掉锁表的进程ID kill id; 3、查询是否锁表 show OPEN TABLES where In_use > 0; ### 140, Mysql解锁行锁定 1.查询 正在执行的事务 SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; 2.杀死进程id(就是上面查询结果集的trx_mysql_thread_id列) kill 线程ID 这样行锁锁定就解决了 查询mysql数据库中还可以使用: 查看正在锁的事务 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; 查看等待锁的事务 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS; 查询mysql数据库中存在的进程 select * from information_schema.PROCESSLIST(show processlist;) 查询是否锁表 show OPEN TABLES where In_use > 0;