阿里php面试题三之 - 阿里电话面试总结
说一下二分查找的思想
前提::线性表中记录必须是有序的,线性表采用顺序存储
原理:在有序表中,取中间记录作为比较对象,若给定的值和中间记录的关键字相同,则查找成功;如果查找对象小于中间记录的关键字,则在中间记录的左半部分继续查找;否则在右半区查找.
时间复杂度: O(log(n))
如何判断链表中是否有环
原理:用两个指针,pSlow,pFast,就是一个慢一个快
慢的一次跳一步,
快的一次跳两步,
什么时候快的追上慢的了(就是pSlow == pFast || pSlow->next == pFast),就表示有环。
代码如下:
#include <stdio.h>
typedef struct Node{
int val;
Node *next;
}Node,*pNode;
//判断是否有环
bool isLoop(pNode pHead)
{
pNode fast = pHead;
pNode slow = pHead;
//如果无环,则fast先走到终点
//当链表长度为奇数时,fast->Next为空
//当链表长度为偶数时,fast为空
while( fast != NULL && fast->next != NULL){
fast = fast->next->next;
slow = slow->next;
//如果有环,则fast会超过slow一圈
if(fast == slow){
break;
}
}
if(fast == NULL || fast->next == NULL ){
return false;
}else{
return true;
}
}
//计算环的长度
int loopLength(pNode pHead){
if(isLoop(pHead) == false)
return 0;
pNode fast = pHead;
pNode slow = pHead;
int length = 0;
bool begin = false;
bool agian = false;
while( fast != NULL && fast->next != NULL){
fast = fast->next->next;
slow = slow->next;
//超两圈后停止计数,挑出循环
if(fast == slow && agian == true)
break;
//超一圈后开始计数
if(fast == slow && agian == false){
begin = true;
agian = true;
}
//计数
if(begin == true)
++length;
}
return length;
}
//求出环的入口点
Node* findLoopEntrance(pNode pHead){
pNode fast = pHead;
pNode slow = pHead;
while( fast != NULL && fast->next != NULL){
fast = fast->next->next;
slow = slow->next;
//如果有环,则fast会超过slow一圈
if(fast == slow){
break;
}
}
if(fast == NULL || fast->next == NULL)
return NULL;
slow = pHead;
while(slow != fast){
slow = slow->next;
fast = fast->next;
}
return slow;
}
说一下cookie和session的区别
- 简单的描述:cookie存在客户端,session 存在服务器端。cookie分两种:一种叫会话cookie是没有设置过期时间,当关闭浏览器后cookie将消失;另一种是设置了过期时间叫持久cookie,这种cookie存储在磁盘中关闭浏览器后cookie不会消失。
- 就安全性来说cookie存在客户端的磁盘上对用户透明session存在服务器端而且sessionID是加密的相对来说seesion较安全。
- 用户的会话通过cookie中存储的session id 来和服务器端的session进行关联从而保持正常的会话。
如果把cookie 禁掉session还能用吗?
- 通过url传值,把session id附加到url上(缺点:整个站点中不能有纯静态页面,因为当是纯静态页面session id 将无法继续向后传了)
- 通过隐藏表单,把session id 放到表单的隐藏文本框中同表单一块提交过去(缺点:不适用标签这种直接跳转的非表单的情况)
- 直接配置php.ini文件,将php.ini文件里的session.use_trans_sid= 0设为1,
- 用文件、数据库等形式保存Session ID,在跨页过程中手动调用
session都是可以存在哪?
数据库、缓存、文件
PHP 如何获取客户端的IP地址?
$_SERVER[‘REMOTE_ADDR’] :通过全局数组来获得
getenv(‘REMOTE_ADDR’) :通过环境变量来获得
用$_SERVER获取的IP地址有什么问题?
当客户机使用代理的时候获取不到真实的IP地址
isset()和array_key_exists()有什么区别?
- 对于数组值的判断不同,对于值为null或”或false,isset返false、array_key_exists返回true 执行效率不同,isset是内建运算符,array_key_exists是php内置函数,isset要快一些
- 当用isset访问一个不存在索引数组值时,不会引起一个E_NOTICE的php错误消息 array_key_exists 会调用get_defined_vars判断数组变量是否存在,isset不用
HTTP请求头和相应头信息都有哪些?
请求头:
Accept: text/html,image/*(浏览器可以接收的类型)
Accept-Charset: ISO-8859-1(浏览器可以接收的编码类型)
Accept-Encoding: gzip,compress(浏览器可以接收压缩编码类型)
Accept-Language: en-us,zh-cn(浏览器可以接收的语言和国家类型)
If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT(某个页面缓存时间)
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)(浏览器相关信息)
Cookie:(浏览器暂存服务器发送的信息)
Connection: close(1.0)/Keep-Alive(1.1)(HTTP请求的版本的特点)
Date: Tue, 11 Jul 2000 18:23:51 GMT(请求网站的时间)
响应头:
Server:apache tomcat(服务器的类型)
Content-Encoding: gzip(服务器发送的压缩编码方式)
Content-Length: 80(服务器发送显示的字节码长度)
Content-Language: zh-cn(服务器发送内容的语言和国家名)
Content-Type: image/jpeg; charset=UTF-8(服务器发送内容的类型和编码类型)
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT(服务器最后一次修改的时间)
Refresh: 1;url=http://www.it315.org(控制浏览器1秒钟后转发URL所指向的页面)
Content-Disposition: attachment; filename=aaa.jpg(服务器控制浏览器发下载方式打开文件)
Transfer-Encoding: chunked(服务器分块传递数据到客户端)
Set-Cookie:SS=Q0=5Lb_nQ; path=/search(服务器发送Cookie相关的信息)
Expires: -1(服务器控制浏览器不要缓存网页,默认是缓存)
Cache-Control: no-cache(服务器控制浏览器不要缓存网页)
Pragma: no-cache(服务器控制浏览器不要缓存网页)
Connection: close/Keep-Alive(HTTP请求的版本的特点)
Date: Tue, 11 Jul 2000 18:23:51 GMT(响应网站的时间)
说一下HTTP常用的状态码并解释涵义
一些常见的状态码为: 200 – 服务器成功返回网页 304 – 未修改 403 – 服务器拒绝请求 404 – 请求的网页不存在 502 – 网关错误 503 – 服务器超时
详解:常用的HTTP状态码
HTTP常见的请求类型都有哪些?区别是什么?
get:请求的数据随HTTP请求头发过去 post:请求的数据在HTTP请求头发过去之后再发过去 get方法的数据大小是有一定限制的。而且发送的数据容易被人看到。>而post就没有这些特点
说一下PHP中的error_reporting是干嘛用的
error_reporting() 设置 PHP 的报错级别并返回当前级别。
说一下错误界别都是有哪些,如何自定义错误处理级别?
E_WARNING 非致命的 run-time 错误。不暂停脚本执行。 E_NOTICE Run-time 通知。脚本发现可能有错误发生,但也可能在脚本正常运行时发生 E_USER_ERROR 致命的用户生成的错误。 E_USER_WARNING 非致命的用户生成的警告。 E_USER_NOTICE 用户生成的通知。 E_RECOVERABLE_ERROR 可捕获的致命错误。 E_ALL 所有错误和警告,除级别 E_STRICT 以外
自定错误处理
PHP 的默认错误处理程序是内建的错误处理程序。可以使用set_error_handler(“函数名称”)来自定义错误处理使其仅应用到某些错误,
说一下面向对象中类的概念,并简单举例说明一下
按专业的概念说就是“具有相同属性和服务的同一类事物的抽象”。类是一个抽象的概念。例如:人类。
常用的数据库引擎有哪些
我的回答:MYISAM 和 InnoDB。然后就抛出了下一个问题
MYISAM 和 InnoDB的区别是什么?
MYISAM不支持事务InnoDB支持事务 MYISAM是表级锁 由于是表级锁,对高并发性的update效率较低;InnoDB是行级锁由于是行级锁,对高并发性的update效率相对较高 MYISAM支持全文索引InnoDB不支持全文索引 MYISAM使用用于大量select操作的数据库,InnoDB适合用于执行大量的INSERT或UPDATE操作的数据库
如何优化数据库?
创建相应的索引:索引有助于提高检索性能,但过多或不当的索引也会导致系统低 效。因为用户在表中每加进一个索引,数据库就要做更多的工作。过多的索引甚至会导致索引碎片。 分表:针对每个时间周期产生大量的数据,可以考虑采用一定的策略将数据存到多个数据表中 分库:是将系统按照模块相关的特征分布到不同的数据中,以提高系统整体负载能力,如:读写分离 sql优化:
- in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据
- 尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描 SELECT * FROM T1 WHERE F1/2=100 应改为: SELECT * FROM T1 WHERE F1=100*2
- 充分利用连接条件,在某种情况下,两个表之间可能不只一个的连接条件,这时在 WHERE 子句中将 连接条件完整的写上,有可能大大提高查询速度。 例: SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO 改成 SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO AND A.ACCOUNT_NO=B.ACCOUNT_NO
如何对比查看两条sql语句的执行效果?
可以收用explain 进行查看。例如:explain select * from user_info;
根据数据设计数据库(考虑优化):“学生”,“成绩”,“课程”
这个就没什么好说的了,就是平时创建数据库的那一套东西什么索引、外键、等等
Linux中统计一个文件中指定字符出项的次数
grep -o ‘搜索的字符’ file | wc -l