逻辑题

以下是逻辑题

  1. 你用什么方法检查php脚本的执行效率(通常是脚本执行时间)和数据库SQL的效率(通常是数据库Query时间),并定位和分析脚本执行和数据库查询的瓶颈所在?
    执行效率
    1, 代码脚本里计时。
    2, xdebug统计函数执行次数和具体时间进行分析。,最好使用工具winCacheGrind分析
    3, 在线系统用strace跟踪相关进程的具体系统调用。

    $begin=microtime(true); //获取程序开始执行的时间
    // some code here 待执行的代码
    $stop=microtime(true); //获取程序执行结束的时间
    list($m0,$s0)=explode(" ",$begin);
    list($m1,$s1)=explode(" ",$stop);
    $runtime=($s1+$m1-$s0-$m0)*1000;
    echo '<br />当前脚本执行时间:'.$etime-$stime.'微秒'; 

    数据库SQL的效率
    sql的explain(mysql),
    启用slow query log记录慢查询。
    通常还要看数据库设计是否合理,需求是否合理等。

  2. tcp**三次握手的过程,**accept发生在三次握手哪个阶段?

      分析:
      accept发生在三次握手之后。
      第一次握手:客户端发送syn包(syn=j)到服务器。
      第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个ASK包(ask=k)。
      第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)。

      三次握手完成后,客户端和服务器就建立了tcp连接。这时可以调用accept函数获得此连接。

  3. UDP协议通讯时怎样得知目标机是否获得了数据包
      分析:
      可以在每个数据包中插入一个唯一的ID,比如timestamp或者递增的int
      发送方在发送数据时将此ID和发送时间记录在本地
      接收方在收到数据后将ID再发给发送方作为回应。
      发送方如果收到回应,则知道接收方已经收到相应的数据包;如果在指定时间内没有收到回应,则数据包可能丢失,需要重复上面的过程重新发送一次,直到确定对方收到。

  4. 统计论坛在线人数分布
    求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID**从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒**。
      分析:
      一天总共有 3600*24 = 86400秒。
      定义一个长度为86400的整数数组int delta[86400],每个整数对应这一秒的人数变化值,可能为正也可能为负。开始时将数组元素都初始化为0。
      然后依次读入每个用户的登录时间和退出时间,将与登录时间对应的整数值加1,将与退出时间对应的整数值减1。
      这样处理一遍后数组中存储了每秒中的人数变化情况。
      定义另外一个长度为86400的整数数组int online_num[86400],每个整数对应这一秒的论坛在线人数。
      假设一天开始时论坛在线人数为0,则第1秒的人数online_num[0] = delta[0]。第n+1秒的人数online_num[n] = online_num[n-1] + delta[n]
      这样我们就获得了一天中任意时间的在线人数。
  5. 10G个数中找到中数
    1, 把整数分成256M段,每段可以用64位整数保存该段数据个数,256M*8 = 2G内存,先清0
    2,读10G整数,把整数映射到256M段中,增加相应段的记数
    3,扫描256M段的记数,找到中位数的段和中位数的段前面所有段的记数,可以把其他段的内存释放
    4,因中位数段的可能整数取值已经比较小(如果是32bit整数,当然如果是64bit整数的话,可以再次分段),对每个整数做一个记数,再读一次10G整数,只读取中位数段对应的整数,并设置记数。
    5,对新的记数扫描一次,即可找到中位数。
    如果是32bit整数,读10G整数2次,扫描256M记数一次,后一次记数因数量很小,可以忽略不记(设是32bit整数,按无符号整数处理
    整数分成256M段? 整数范围是0 - 2^32 - 1 一共有4G种取值,4G/256M = 16,每16个数算一段 0-15是1段,16-31是一段,…
    整数映射到256M段中? 如果整数是0-15,则增加第一段记数,如果整数是16-31,则增加第二段记数,…
    其实可以不用分256M段,可以分的段数少一写,这样在扫描记数段时会快一些,还能节省一些内存)

  6. 两个整数集合A和B,求其交集
     1. 读取整数集合A中的整数,将读到的整数插入到map中,并将对应的值设为1
     2. 读取整数集合B中的整数,如果该整数在map中并且值为1,则将此数加入到交集当中,并将在map中的对应值改为2。
     通过更改map中的值,避免了将同样的值输出两次。

  7. 找出1到10w中没有出现的两个数字
    有1到10w这10w个数,去除2个并打乱次序,如何找出那两个数?
    申请10w个bit的空间,每个bit代表一个数字是否出现过。
     开始时将这10w个bit都初始化为0,表示所有数字都没有出现过。
     然后依次读入已经打乱循序的数字,并将对应的bit设为1。
     当处理完所有数字后,根据为0的bit得出没有出现的数字。
     首先计算1到10w的和,平方和。
     然后计算给定数字的和,平方和。
     两次的到的数字相减,可以得到这两个数字的和,平方和。
     所以我们有
     x + y = n
     x^2 + y^2 = m
     解方程可以得到x和y的值。

  8. 根据上排的数填写下排的数,并满足要求。
      根据上排给出十个数,在其下排填出对应的十个数, 要求下排每个数都是上排对应位置的数在下排出现的次数。上排的数:0,1,2,3,4,5,6,7,8,9。
  9. 判断数字是否出现在40亿个数中?
      给40亿个不重复的unsigned int的整数,没排过序的,然后再给几个数,如何快速判断这几个数是否在那40亿个数当中?
      分析:
      unsigned int 的取值范围是0到2^32-1。我们可以申请连续的2^32/8=512M的内存,用每一个bit对应一个unsigned int数字。首先将512M内存都初始化为0,然后每处理一个数字就将其对应的bit设置为1。当需要查询时,直接找到对应bit,看其值是0还是1即可。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值