阿里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还能用吗?

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请求头和相应头信息都有哪些?

说一下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