面试中可以学习到很多自己不太擅长的知识
2018-08-28 广州爱卡的米教育
使用PHP做单点登录
https://github.com/evangui/sso
https://segmentfault.com/q/1010000005811793
PHP原生获取POST传JSON数据
- 第一种:
$_POST
content-type
为application/x-www-form-urlencoded
,这是post默认的数据格式,在使用jquery的ajax来post数据的时候默认就是这种方式,这种方式传输的数据形式为:username=admin&password=123456,在服务器接收的时候就是使用最常用的$_POST
方式,获取username则采用$_POST['username']
即可正常获取。
- 第二种:使用
file_get_contents("php://input")
对于未指定 Content-Type 的POST数据,则可以使用
file_get_contents("php://input");
来获取原始数据。
事实上,用PHP接收POST的任何数据均使用本方法。而不用考虑Content-Type
,包括二进制文件流也是可行的。
同$HTTP_RAW_POST_DATA
比起来,它给内存带来的压力较小,并且不需要任何特殊的php.ini
设置。php://input
无法读取Content-Type为multipart/form-data
的POST数据,需要设置php.ini中的always_populate_raw_post_data
值为On才可以。php://input
读取不到$_GET
数据。是因为$_GET
数据作为query_path
写在http请求头部(header)的PATH
字段,而不是写在http
请求的body
部分。
- 第三种:使用全局变量
$GLOBALS['HTTP_RAW_POST_DATA']
在
$GLOBALS['HTTP_RAW_POST_DATA']
存放的是POST过来的原始数据。
但$GLOBALS['HTTP_RAW_POST_DATA’]
中是否保存POST过来的数据取决于centent-Type
的设置,只有在PHP在无法识别的Content-Type的情况下,才会将POST过来的数据原样地填入变量$GLOBALS['HTTP_RAW_POST_DATA’]
中,象Content-Type=application/x-www-form-urlencoded时,该变量是空的。
另外,它同样无法读取Content-Type为multipart/form-data
的POST数据,也需要设置php.ini中的always_populate_raw_post_data
值为On,PHP才会总把POST数据填入变量$http_raw_post_data
。
Linux下进程之间的交流方式
- 管道 :
管道(Pipe)及命名管道(named pipe):管道(匿名管道)可用于具有亲缘关系进程间的通信,命名管道,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
管道是进程间通信中最古老的方式,它包括无名管道和有名管道两种,前者用于父进程和子进程间的通信,后者用于运行于同一台机器上的任意两个进程间的通信。
- 消息队列 :
消息队列是消息的链表,包括Posix消息队列、SystemV消息队列。具有写权限的进程可以按照一定的规则向消息队列中添加新消息;对消息队列有读权限的进程则可以从消息队列中读取消息。
消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限(4096字节)等缺点
消息队列用于运行于同一台机器上的进程间通信,它和管道很相似,是一个在系统内核中用来保存消息的队列,它在系统内核中是以消息链表的形式出现。消息链表中节点的结构用msg声明。
事实上,它是一种正逐渐被淘汰的通信方式,我们可以用流管道或者套接口的方式来取代它,所以,我们对此方式也不再解释,也建议读者忽略这种方式。
- 共享内存 :
共享内存使得多个进程可以访问同一块内存空间,是最快的IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥
共享内存是运行在同一台机器上的进程间通信最快的方式,因为数据不需要在不同的进程间复制。通常由一个进程创建一块共享内存区,其余进程对这块内存区进行 读写。得到共享内存有两种方式:映射/dev/mem设备和内存映像文件。前一种方式不给系统带来额外的开销,但在现实中并不常用,因为它控制存取的将是 实际的物理内存,在Linux系统下,这只有通过限制Linux系统存取的内存才可以做到,这当然不太实际。常用的方式是通过shmXXX函数族来实现利 用共享内存进行存储的。
首先要用的函数是shmget,它获得一个共享存储标识符。#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>int shmget(key_t key, int size, int flag);
这个函数有点类似大家熟悉的malloc函数,系统按照请求分配size大小的内存用作共享内存。Linux系统内核中每个IPC结构都有的一个非负整数 的标识符,这样对一个消息队列发送消息时只要引用标识符就可以了。这个标识符是内核由IPC结构的关键字得到的,这个关键字,就是上面第一个函数的 key。数据类型key_t是在头文件sys/types.h中定义的,它是一个长整形的数据。在我们后面的章节中,还会碰到这个关键字。
当共享内存创建后,其余进程可以调用shmat()将其连接到自身的地址空间中。
void *shmat(int shmid, void *addr, int flag);
shmid为shmget函数返回的共享存储标识符,addr和flag参数决定了以什么方式来确定连接的地址,函数的返回值即是该进程数据段所连接的实际地址,进程可以对此进程进行读写操作。
使用共享存储来实现进程间通信的注意点是对数据存取的同步,必须确保当一个进程去读取数据时,它所想要的数据已经写好了。通常,信号量被要来实现对共享存 储数据存取的同步,另外,可以通过使用shmctl函数设置共享存储内存的某些标志位如SHM_LOCK
、SHM_UNLOCK
等来实现。
- 信号量 :
主要作为进程之间以及同一进程的不同线程之间的同步和互斥手段。
信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:
(1) 测试控制该资源的信号量。
(2) 若此信号量的值为正,则允许进行使用该资源。进程将信号量减1。
(3) 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。
(4) 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。
维护信号量状态的是Linux内核操作系统而不是用户进程。我们可以从头文件/usr/src/linux/include /linux /sem.h 中看到内核用来维护信号量状态的各个结构的定义。信号量是一个数据集合,用户可以单独使用这一集合的每个元素。要调用的第一个函数是semget,用以获 得一个信号量ID。
- 套接口(Socket) :
这是一种更为一般的进程间通信机制,它既可用于同一台计算机上不同进程间通信,也可用于在不同计算机上的进程间建立基于网络的通信。通常,它主要用于网络中不同机器之间的进程间通信。
套接口(socket)编程是实现Linux系统和其他大多数操作系统中进程间通信的主要方式之一。我们熟知的WWW服务、FTP服务、TELNET服务 等都是基于套接口编程来实现的。除了在异地的计算机进程间以外,套接口同样适用于本地同一台计算机内部的进程间通信。关于套接口的经典教材同样是 Richard Stevens编著的《Unix网络编程:联网的API和套接字》,清华大学出版社出版了该书的影印版。它同样是Linux程序员的必备书籍之一。
Linux下查询Nginx的进程列表(使用Nginx自带)
- 第一种方法:查看进程列表并过滤
1 | ps -ef | grep nginx |
- 第二种方法:直接查看进程id
1 | ps -C nginx -o pid |
这种直接返回pid的方式比较适合跟其他程序结合使用,比如在shell/python脚本中执行这个命令拿到pid,让后根据pid来判断Nginx是否启动。
- 第三种方法:使用netstat命令
1 | netstat -anp | grep :80 |
- 第四种方法:使用lsof命令
1 | lsof -i:80 |
必须熟悉HTTP协议、TCP协议等
人事技术一起面试的,技术要求抛去框架,对原生基础要求多。
2018-08-28 广州纵思
OA系统
OA系统的英文全称是:Office Automation System ,意为办公自动化系统。
办公自动化(OA)是面向组织的日常运作和管理,员工及管理者使用频率最高的应用系统.
待做: 使用Laravel
/ThinkPHP
各做一个OA
系统 (曾经用TP3.2
做过OA
系统)
ERP系统
ERP系统是企业资源计划(Enterprise Resource Planning )的简称,是指建立在信息技术基础上,集信息技术与先进管理思想于一身,以系统化的管理思想,为企业员工及决策层提供决策手段的管理平台。它是从MRP(物料需求计划)发展而来的新一代集成化管理信息系统,它扩展了MRP的功能,其核心思想是供应链管理。它跳出了传统企业边界,从供应链范围去优化企业的资源,优化了现代企业的运行模式,反映了市场对企业合理调配资源的要求。它对于改善企业业务流程、提高企业核心竞争力具有显著作用。
PHP跨库查询数据
如果是两个不同引擎的数据库,例如MYSQL和SQL SERVER,或者不同服务器上两个数据库,是无法直接关联查询的,PHP可以同时连接两个数据库,在循环里面的一次一条数据的相互操作。
如果是同一服务器、同一引擎下的两个数据库,一般都可以直接操作,也就是完全当一个数据库使用,只是根据不同数据库引擎的语法要求写SQL就行的,对于非当前数据库里面的表,有的数据库是使用冒号(INFORMIX等),有的使用圆点(MSSQL、MYSQL、ORACLE等)。
例如MYSQL下查询web和test两个数据库里面的表的语句:
$sql = “SELECT * FROM test.tab1, web.tab2 WHERE tab1.id=tab2.id”;
Thinkphp跨库连表查询
1 | db1 数据库1 |
Laravel5.5 使用仓库模式处理业务报表(多至34十张表)
人事和技术都过了,说要评估,然后没有然后了,
2018-08-29 广州伊思高
环境不适合,看了下就直接走了没有面试。
来自小鸡的面试题:
- array+array 和array_merge()的区别?
- 常见的网络攻击? 解决方案?
array+array 和array_merge()的区别?
- 当下标为数值时,array_merge()不会覆盖掉原来的值,但array+array合并数组则会把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉(不是覆盖).
- 当下标为字符时,array+array仍然把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉,但array_merge()此时会覆盖掉前面相同键名的值.
常见的网络攻击? 解决方案?
XSS
XSS,Cross-site script,跨站脚本攻击。它可以分为两类:反射型和持久型。
反射型XSS攻击场景
:用户点击嵌入恶意脚本的链接,攻击者可以获取用户的cookie信息或密码等重要信息,进行恶性操作。- 解决:开启cookie的HttpOnly属性,禁止JavaScript脚本读取cookie信息
持久型XSS攻击场景
:攻击者提交含有恶意脚本的请求(通常使用<script>
标签),此脚本被保存在数据库中。用户再次浏览页面,包含恶意脚本的页面会自动执行脚本,从而达到攻击效果。这种攻击常见于论坛,博客等应用中。- 解决:前端提交请求时,转义
<
为<
,转义>
为>
;或者后台存储数据时进行特殊字符转义。
建议后台处理,因为攻击者可以绕过前端页面,直接模拟请求,提交恶意
- 解决:前端提交请求时,转义
SQL注入
- 攻击者在HTTP请求中注入恶意SQL命令,例如,drop table users,服务器用请求参数构造数据库SQL命令时,恶意SQL被执行。
- 解决:后台处理,例如,使用预编译语句
PreparedStatement
进行预处理。
- 解决:后台处理,例如,使用预编译语句
CSRF
CSRF,Cross-site request forgery,跨站请求伪造。这种方式是利用浏览器的cookie或服务器的session策略,盗取用户信息,模拟用户向第三方网站发送恶意请求。
- 因为从WEB页面产生的所以请求,包括文件请求,都会带上cookie,这样,只要用户在网站A的会话还没有过期,访问恶意网站B时就可能被动发出请求到网站A,同时携带cookie信息,从而达到伪造用户进行恶性操作。
- 解决方案:
- 提交请求中携带
Token
,并且每次请求的Token值都是合法的随机数。
注意:使用时注意token
的私密性,不要以url
参数的形式发送(不要使用GET
)。尽量采用POST
操作,以form
表单或者AJAX
的形式提交。 referer check
:根据http request
信息里面的referer
参数(请求源),验证请求源是否合法。
注意:某些情况下,浏览器不会发送referer
参数,比如,从https
跳转到http
,为了安全性不会发送referer
。
按照osi七层协议,可以分为:
- 物理层 线路侦听
- 数据链路层 mac_flood
- 网络层 arp_poison,icmp_redirection
- 传输层 tcp_flood(包含ack_flood和syn_flood),udp_flood(ntp,dns)
- 应用层 connection_flood,http_get等等
按照攻击目的,可以分为:
- 中间人攻击(为了获得网络数据):mac_flood,arp_poison,icmp_redirection
- 拒绝服务攻击:tcp_flood,udp_flood,connection_flood,http_get
按照攻击者的位置,可以分为:
- 攻击者必须与攻击目标处于同一网段:mac_flood,arp_poison,icmp_redirection,线路侦听
- 不必处于同一网段:其他
2018-08-29 广州晨风
没有人事,直接技术,技术过了
面试半天过了, 然后说要搬家到海珠区问我去不去, 我醉了 这种要搬家的面试个什么劲。。。
2018-08-30 广州微世纪
你怎么做登录?你怎么知道是谁登录? (听到这个问题我就想笑)
由于HTTP协议是无状态的,服务器无法知道两次访问是不是来自同一个人。
这里就使用到COOKIE技术了,使用COOKIE可以解决以上问题,让服务器知道用户是否登录。
https://blog.csdn.net/looksunli/article/details/9799395
1 | setcookie($name, $value, $expire, $path, $domain, $secure) |
商城的核心模块?
- 用户认证管理模块
- 商品检索引擎模块
- 广告管理与发布系统功能模块
- 订单系统模块、购物车模块。
怎么实现购物车模块?未登录怎么加入购物车?实现未登录统计加入购物车的商品?
搜索商品名称,并跳转到商品页面,并且搜索关键字高亮显示
附笔试题
- $this,self,parent的区别?
- 命名空间有什么作用?
- JSON和JSONP的区别和注意细节?
- MVC分层是什么?TP5各自需要继承什么?
- trait功能是什么?
- TP5和TP3在控制器上的区别?
- TP参数绑定的定义和使用示例?
$this,self,parent的区别?
从字面上来理解,分别是指
这
、自己
、父亲
。先初步解释一下,this
是指向当前对象的指针(可以看成C里面的指针),self
是指向当前类的指针,parent
是指向父类的指针
- $this是在实例化的时候来确定指向谁
- self是指向类本身,也就是self是不指向任何已经实例化的对象,一般self使用来指向类中的静态变量
- 使用parent来调用父类的构造函数
命名空间有什么作用?
命名空间主要解决class类
/function 函数
/常量
等一些的命名冲突问题
JSON和JSONP的区别和注意细节?
JSON
下面是jquery的ajax请求,数据类型为json,它是以json格式在前后台进行数据的传输,它与局限性就是不能跨域请求,这是为了网络数据的安全所制定的规则。
1 | $.ajax({ |
JSONP
大家都知道script标签是可以跨域请求的,jsonp的原理就是通过script的src,将函数作为src请求地址的参数来传递数据,所以jsonp只有get一种传输方式。
下面是jsonp的数据交互,首先定义一个回调函数,定义dataType类型为jsonp,将函数作为参数传输给后台,它与json相比是多了一层函数。
1 | <script type="text/javascript"> |
至于什么时候用json什么时候用jsonp?我就一个原则,能使用json的时候都是用json,只有必须要跨域请求时才使用jsonp。
MVC分层是什么?TP5各自需要继承什么?
视图层view
:用于展示数据,与用户进行交互。控制层controller
:用于分发控制到来的请求,并调用模型层与数据库进行交互,以及将数据返回给视图层展示。模型层model
:数据模型,它与数据库进行交互,进行CURD操作。
继承:
controller
:use think\Controller;
model
:use think\Model;
view
:use think\View;
trait功能是什么?
Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。
Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。
TP5和TP3在控制器上的区别?
控制器的命名空间有所调整,并且可以无需继承任何的控制器类。
- 应用命名空间统一为app(可定义)而不是模块名;
- 控制器的类名默认不带
Controller
后缀,可以配置开启use_controller_suffix
参数启用控制器类后缀; - 控制器操作方法采用
return
方式返回数据 而非直接输出; - 废除原来的操作前后置方法;
- 增加
beforeActionList
属性定义前置操作; - 支持任意层次的控制器定义和访问;
- URL访问支持自动定位控制器;
TP参数绑定的定义和使用示例?
参数绑定是指绑定一个参数到预处理的SQL语句中的对应命名占位符或问号占位符指定的变量,并且可以提高SQL处理的效率,需要数据库驱动类的支持,目前只有PDO和Sqlsrv驱动支持参数绑定功能。
https://www.kancloud.cn/beyondzgz/tp/52559
手动绑定
参数手动绑定需要调用连贯操作的bind方法,例如:
1 | $Model = M('User'); |
自动绑定
对于某些操作的情况(例如模型的写入和更新方法),可以支持参数的自动绑定,例如:首先需要开启DB_BIND_PARAM
配置参数:
1 | $Model = M('User'); |
2018-08-30 广州众享
以下是我听过最智障的面试, 来自一位老年人程序员(至少35+,看上去)
你上家公司做什么,你负责什么,具体点。。。
你上上家公司做什么,你负责什么,具体点。。。
你上上家公司坐什么,你负责什么,具体点。。。
微信支付怎么做的, 具体流程说一下,具体点。。。
广州众享和广州微世纪是一起的,笔试题是一模一样的,然后还分别给了一份面试邀请。
2018-08-31 广州玩动网络(手趣网络、果玩网络)
面试让人很舒服,这个一定要说。
是做游戏的,需要对游戏相关有了解
Swoole的使用?除此之外别的PHP组件?
微服务?(RabbitMQ,Kafka,etcd,zookeeper)
Facades的作用?不是静态方法为何可以::
调用
Facade其实是一个容器中类的静态代理,他可以让你以静态的方式来调用存放在容器中任何对象的任何方法。
依赖注入的原理?为什么可以这样做?
依赖注入(Dependency Injection)是用于实现控制反转(Inversion of Control)的最常见的方式之一
依赖注入原理(为什么需要依赖注入)
RPC协议?
英文原义:Remote Procedure Call Protocol
中文释义:(RFC-1831)远过程调用协议
MySQL索引优化,慢查询优化?
2018-08-31 广州天启互娱
附笔试题
- 的执行结果是?
- 使用list()函数需要注意什么?
- 请说明php_ini中safe_mode开启影响了哪些函数?
- 请对POSIX风格和兼容Prel风格正则主要函数类比说明?
- 简述PHP垃圾收集机制?
- php查询mysql数据库出现中文乱码解决方法?
- Session和Cookie的区别?
- 数据库优化?
- 如何处理负载和高并发?
请说明php_ini中safe_mode开启影响了哪些函数?
2018-08-31 广州爱拍(不是本人面试)
爱拍面试在下周,这里记录一些爱拍的笔试题
- GET和POST的区别?
- 禁用Cookie后session是否可以正常使用,原理?
- 如何实现多机器Session共享?
- HTTP状态码1,2,3,4,5,6开头的分别什么意思?
- 阐述opcache原理?
- PHPTAL模板引擎,阐述原理
- 写出phpdocumentor 5个tags的名称及其含义?
- 简述对Symfony的了解?
- 简述Symfony中的announce路由原理?
- 最近看过的技术类书记有哪些?
- 写一个函数遍历目录?
- MySQL事务语句?
- Linux常见的shell有哪些?
- Linux下查看磁盘空间命令?
- 写清楚Linux命令统计/etc/passwd/文件下的每个组的人数
- 请简述进程和线程的区别?
- 编写一个Nginx的rewrite规则
- MYSQL有2000W数据,redis中只存20W数据,怎么保证redis都是热点数据?
- 写出HTTP工作过程步骤?
2018-09-03 广州港讯
公司环境很心水,公司团队不大,技术面试问的不深。
- Left Join, Right Join, Inner Join的区别?
- Left Join 时右表为空返回什么?怎么做条件判断?
- Redis的应用场景?(什么时候需要使用Redis)
Left Join, Right Join, Inner Join的区别?
left join(左联接)
: 返回包括左表中的所有记录和右表中联结字段相等的记录right join(右联接)
: 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接)
: 只返回两个表中联结字段相等的行
Left Join 时右表为空返回什么?怎么做条件判断?
1 | A表 |
select aname,bname,score from A left join B on A.id=B.aid where year=’2018’
select aname,bname,score from A left join B on A.id=B.aid and year=’2018’
Redis的应用场景?
缓存
作为Key-Value形态的内存数据库,Redis 最先会被想到的应用场景便是作为数据缓存。而使用 Redis 缓存数据非常简单,只需要通过string类型将序列化后的对象存起来即可,不过也有一些需要注意的地方:
- 必须保证不同对象的 key不会重复,并且使
key
尽量短,一般使用类名(表名)加主键拼接而成。 - 选择一个优秀的序列化方式也很重要,目的是提高序列化的效率和减少内存占用。
- 缓存内容与数据库的一致性,这里一般有两种做法:
- 只在数据库查询后将对象放入缓存,如果对象发生了修改或删除操作,直接清除对应缓存(或设为过期)。
- 在数据库新增和查询后将对象放入缓存,修改后更新缓存,删除后清除对应缓存(或设为过期)。
消息队列
Redis 中list
的数据结构实现是双向链表,所以可以非常便捷的应用于消息队列(生产者 / 消费者模型)。消息的生产者只需要通过lpush
将消息放入 list
,消费者便可以通过rpop
取出该消息,并且可以保证消息的有序性。如果需要实现带有优先级的消息队列也可以选择sorted set
。而pub/sub
功能也可以用作发布者 / 订阅者模型的消息。无论使用何种方式,由于 Redis 拥有持久化功能,也不需要担心由于服务器故障导致消息丢失的情况。
时间轴(Timeline)
list
作为双向链表,不光可以作为队列使用。如果将它用作栈便可以成为一个公用的时间轴。当用户发完微博后,都通过lpush
将它存放在一个 key
为LATEST_WEIBO
的list
中,之后便可以通过lrange
取出当前最新的微博。
下午复试,大致了解,前身是做外包的,所以还有挺多外包。项目较多,除五险一金无其他福利。
排行榜
使用sorted set
和一个计算热度的算法便可以轻松打造一个热度排行榜,zrevrangebyscore
可以得到以分数倒序排列的序列,zrank
可以得到一个成员在该排行榜的位置(是分数正序排列时的位置,如果要获取倒序排列时的位置需要用zcard-zrank
)。
计数器
计数功能应该是最适合 Redis 的使用场景之一了,因为它高频率读写的特征可以完全发挥 Redis 作为内存数据库的高效。在 Redis 的数据结构中,string
、hash
和sorted set
都提供了incr
方法用于原子性的自增操作,下面举例说明一下它们各自的使用场景:
- 如果应用需要显示每天的注册用户数,便可以使用
string
作为计数器,设定一个名为REGISTERED_COUNT_TODAY
的key
,并在初始化时给它设置一个到凌晨0
点的过期时间,每当用户注册成功后便使用incr命令使该key
增长1
,同时当每天凌晨0
点后,这个计数器都会因为key
过期使值清零。 - 每条微博都有点赞数、评论数、转发数和浏览数四条属性,这时用
hash
进行计数会更好,将该计数器的key
设为weibo:weibo_id
,hash
的field
为like_number
、comment_number
、forward_number
和view_number
,在对应操作后通过hincrby
使hash
中的field
自增。 - 如果应用有一个发帖排行榜的功能,便选择
sorted set
吧,将集合的key
设为POST_RANK
。当用户发帖后,使用zincrby
将该用户id
的score
增长1
。sorted set
会重新进行排序,用户所在排行榜的位置也就会得到实时的更新。
好友关系
对于一个用户 A,将它的关注和粉丝的用户 id 都存放在两个 set 中:
A:follow
:存放 A 所有关注的用户 idA:follower
:存放 A 所有粉丝的用户 id
那么通过sinter
命令便可以根据A:follow
和A:follower
的交集得到与 A 互相关注的用户。当 A
进入另一个用户 B
的主页后,A:follow
和B:follow
的交集便是 A 和 B 的共同专注,A:follow
和B:follower
的交集便是 A 关注的人也关注了 B。
分布式锁
在 Redis 2.6.12 版本开始,string的set命令增加了三个参数:
EX
:设置键的过期时间(单位为秒)PX
:设置键的过期时间(单位为毫秒)NX | XX
:当设置为NX
时,仅当 key 存在时才进行操作,设置为XX
时,仅当 key 不存在才会进行操作
由于这个操作是原子性的,可以简单地以此实现一个分布式的锁,例如:
set key "lock" EX 1 XX
如果这个操作返回false
,说明 key
的添加不成功,也就是当前有人在占用这把锁。而如果返回true
,则说明得了锁,便可以继续进行操作,并且在操作后通过del
命令释放掉锁。并且即使程序因为某些原因并没有释放锁,由于设置了过期时间,该锁也会在 1
秒后自动释放,不会影响到其他程序的运行。
倒排索引
倒排索引是构造搜索功能的最常见方式,在 Redis 中也可以通过set
进行建立倒排索引,这里以简单的拼音 + 前缀
搜索城市功能举例:
假设一个城市北京,通过拼音词库将北京
转为beijing
,再通过前缀分词将这两个词分为若干个前缀索引,有:北
、北京
、b
、be…beijin
和beijing
。将这些索引分别作为set
的 key
(例如:index:北
)并存储北京的 id
,倒排索引便建立好了。接下来只需要在搜索时通过关键词取出对应的set
并得到其中的 id
即可。
一些建议
- Redis 速度快是建立在内存数据库基础上的,但是一台服务器的内存要比磁盘金贵许多,所以在项目初期不要想什么都往 Redis 里放,这样当数据量上来后很快内存就会不够用,反而得不偿失。合理的利用有限的内存,将读(写)频繁的热数据放在 Redis 中才能更好感受到它带来的性能提升。
- Redis 虽然提供了
RDB
和AOF
两种持久化方式,但是普遍还是认为 Redis 的持久化并不是很靠谱。这也是我一直不敢尝试彻底的用 Redis 去实现第五点(好友关系)的原因。
2018-09-03 广州深科信
与广州港讯在同一栋楼,24层,人事技术面试了快2个小时。回去等通知,然后说不合适。
技术聊了一个小时,大致围绕我原来的项目
技术问题:
- 购物车表设计?
- 高并发问题?
2018-09-04 广州米妍网研
- 从用户输入
caoxl.com
,到浏览器显示caoxl.com
首页,经历了什么过程?- 订餐系统?
- 美国上线,对接银联支付?
2018-09-04 广州量子云
真·初创公司,没有后端,服务器也没有,办公地点还可以,在万达广场18楼
- 图片库,图床?
- LBS(基于位置服务)?
- Redis实现热点数据?实现好友关系?
- PHP5和PHP7的垃圾回收机制?
- PHP7可选参数机制?
- IP协议,TCP协议,UDP协议的区别?
- 数据库引擎myisam和innodb的区别(至少5点)?
- 多进程和多线程的优缺点?
- strtr和str_replace的区别?
- $a=1,$b=$a,$a=2; 内存分配情况?
- 有哪些数据库锁?
- Redis是什么?Redis的数据类型有哪些?
- MySQL优化手段?
数据库引擎myisam和innodb的区别(至少5点)?
1. 存储结构
- MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。
- InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。
2. 存储空间
- MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。
- InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。
3. 事务支持
- MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
- InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
4. CURD操作
- MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。(因为没有支持行级锁),在增删的时候需要锁定整个表格,效率会低一些。相关的是innodb支持行级锁,删除插入的时候只需要锁定改行就行,效率较高
- InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。
5. 外键
- MyISAM:不支持
- InnoDB:支持
MySQL数据库类型从InnoDB转换为MyISAM
1 | USE 数据库名; |
修改MySQL数据库引擎为INNODB:
- 首先修改my.ini,在[mysqld]下加上:
1 | default-storage-engine=INNODB |
- 用sql语句修改已经建成表的引擎:
1 | alter table 待改表名 type=InnoDB; |
公司需求
- 理解SOA架构体系。
- 有实际的缓存(Redis/Memcache)、MQ(RabbitMQ/NSQ/RocketMQ)使用经验。
- 对MySQL集群,查询和索引优化有深入了解。
- 对主流内存及文件搜索引擎(ElasticSearch、Solr、Sphinx)使用和调优经验。
- 熟悉各类通讯协议(thrift、http、json)有socket编程经验。
- 熟悉分布式、高可用、高并发、可扩展性架构设计。
广州面对面F2F
- Swoole进程池?
- 索引的种类?区别?
- Redis怎么做队列?
- DDos攻击怎么解决?
- 身份伪造攻击怎么解决?
- TP5开发?
- myisam和innodb的区别?如何选择?
- 有那些队列组件?区别?
广州硅碳鼠
- 缓存技术?
- 关系型数据库和非关系型数据库区别?使用?
- 多进程和单进程的优缺点?
- 进程和异步的关系区别?
- Memcache和Redis的优缺点?使用场景?
- MySQL和MongoDB的区别?优缺点?
- 索引优化?索引选择?
- Linix下进程的交流?Nginx和Apache的优缺点?如何选择使用?