最近看到的某公司后端开发工程师面试题,拿来研究学习一下,感觉提高技术,看面试题也是一个挺好的方法:(
Redis Incr 命令将 key 中储存的数字值增一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。(incr具有原子性。)
//先获取相关用户参数并且验证 $redis_lock = $Redis::incr($user_id."alipay_lock"); if($redis_lock <= 1){ $redis::expire($redis_lock,10);//设置超时时间 //数据库操作 //向支付宝发送转账请求操作 $Redis::del($redis_lock); }else{ //返回提示信息,表示转账正在进行 }
file
改为 redis
会提高速度,由于redis是在内存中读取的,其读取速度必然比在文件中读取速度快,同时解决了session共享的问题。$fp=fopen('/tmp/lock.txt','w+'); if (flock($fp,LOCK_EX)){
//do something flock($fp,LOCK_UN); }else{ echo 'Couldn't lock the file !'; } fclose($fp);
打开文件后,先对文件加锁。加锁后,意味着只有这个进程可以访问lock.txt文件 。在操作完成后,打开锁。这个方法操作比较简易,对于需要同步执行的程序出错概率低的情况,较为适用;可是它的缺点是没有超时时间的限制,一旦在do something的时候出现什么问题。这个锁就解不开了。会占用cpu。其他进程也无法执行该操作了。
2)可以用redis缓存实现锁。前面答案已经描述。这个适用于随机响应的情况,如果需要响应每一个请求,且按请求的先后顺序进行依次处理。则不太适合,应当构建队列。
3)使用队列来响应并发请求(队列依然依赖redis的list数据结构实现)。来一个排队一个,依次处理。处理程序可以用php写一个守护程序。按顺序去redis里的list去取请求处理,如果list为空,则等待1秒再去取。(大概逻辑是这样)。
4.这个网上答案很多。
区别:1)myisam的text支持索引,innodb不支持;
2)innodb支持事务,myisam不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;
3)innodb有行锁,myisam只是表锁;
4)myisam的查询效率高于innodb;
5)InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
6)InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;
7)InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
参考:https://www.zhihu.com/question/20596402
5.分布式拒绝服务(DDoS:Distributed Denial of Service)攻击指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力。(来源百度百科)
如何防范:1)关闭不必要的服务,如只开放80端口响应Http请求;2)获取可疑攻击ip,加入黑名单,禁止访问;3)使用cdn服务,将流量分散到网络各个节点,减少对服务器的压力等等。(具体的方法网络上很多,有各种的总结和攻防的案例)。
6. 简单来说,http是明文传输的协议,客户端和服务器通讯的所有内容都明文暴露在公共的互联网上,一旦http包被截获,信息就会被别人获取;https则是加密传输的协议,客户端和服务器通讯的关键内容都是有密匙加密过的,虽然也是在公共的网络上传递,但是通讯的包被截获,别人拿到加密后的内容也无法解密获取到通讯的内容。具体的介绍可以参考前端牛人小卡的一篇介绍,写的很详细。虽然https的浏览器私人密匙怎么生成我还是不太了解,是不是可以穷举?
2018/5/9 服务器发给客户端的证书的数字签名,需要客户端用CA的公匙解密。这个CA的公匙是保存在浏览器或者操作系统中的。所以使用php的时候依然可以做https请求!
http包泄露的方式: 1)自己的电脑被入侵,接受和发送的http包都会被黑客监听获取到;2)电脑所在的局域网关被黑客入侵,http包也会被截获;3)在公共互联网上也有很多节点(如代理服务器)可能被截获。
7. php7的新特性有很多,最实惠的是性能(无论是服务器的cpu占用率,响应请求数量还是请求处理时间)提高了至少一倍。参考http://hansionxu.blog.163.com/blog/static/24169810920158704014772/,和鸟哥的个人网站。有空我需要再把php的底层实现再看看吧。
8. 防止sql注入的方法:1)严格限制用户输入(长度,类型,特殊字符);2)使用mysql_escape_string转义特殊字符;3)使用pdo模式操作数据库,预编译语句,参数化查询,分开的发送到数据库服务端进行解析。
具体的php绑定和分预编译语句,变量参数化两次传递给msql服务器的细节内容可以参考月影无痕的分析。至于将SQL模板和变量是分两次发送给MySQL后,mysql的处理细节,我继续使用google。查询到文章:预编译语句(Prepared Statements)介绍,以MySQL为例 。里面介绍了预编译语句在mysql端是如何实现的,但是还是没有解决我的核心问题,预编译语句为什么能防止sql注入? 知乎相关问题中,不二的回答提到了占位符的概念很有意思,sql语句在包含占位符的情况下编译,理论上来说,以后就不会再改变了。这是否决定了该语句的运行结果被限制在一定的范围内了,后面用参数代替占位符(会将参数字符串转义)后的结果也会限定在这个范围内? 有待于进一步研究吧。
9.MySQL之间数据复制的基础是二进制日志文件(binary log file)。一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”的方式记录在二进制日志中,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化,如果发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制。
具体参考:https://www.cnblogs.com/gl-developer/p/6170423.html
这个时候我又脑洞大开,既然已经想到了php的异步调用了。那么会不会有像其他语言里面一样的回调函数存在呢,比如js里面的call这样的。于是google了一样还真有这样的东西。不过它是同步文件中的,如果异步调用非得要回调,可以把回调的一些参数放在请求参数中,这样在请求的文件中调用回调的内容就可以了。
关于php的回调函数实现,可以参考:http://www.cnitblog.com/CoffeeCat/archive/2009/04/21/56541.html