面试/笔试实战

面试中可以学习到很多自己不太擅长的知识

2018-08-28 广州爱卡的米教育

使用PHP做单点登录

https://github.com/evangui/sso
https://segmentfault.com/q/1010000005811793

PHP原生获取POST传JSON数据

  • 第一种:$_POST

content-typeapplication/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下进程之间的交流方式

    1. 管道 :

管道(Pipe)及命名管道(named pipe):管道(匿名管道)可用于具有亲缘关系进程间的通信,命名管道,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

管道是进程间通信中最古老的方式,它包括无名管道和有名管道两种,前者用于父进程和子进程间的通信,后者用于运行于同一台机器上的任意两个进程间的通信。

    1. 消息队列 :

消息队列是消息的链表,包括Posix消息队列、SystemV消息队列。具有写权限的进程可以按照一定的规则向消息队列中添加新消息;对消息队列有读权限的进程则可以从消息队列中读取消息。
消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限(4096字节)等缺点

消息队列用于运行于同一台机器上的进程间通信,它和管道很相似,是一个在系统内核中用来保存消息的队列,它在系统内核中是以消息链表的形式出现。消息链表中节点的结构用msg声明。
事实上,它是一种正逐渐被淘汰的通信方式,我们可以用流管道或者套接口的方式来取代它,所以,我们对此方式也不再解释,也建议读者忽略这种方式。

    1. 共享内存 :

共享内存使得多个进程可以访问同一块内存空间,是最快的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_LOCKSHM_UNLOCK等来实现。

    1. 信号量 :

主要作为进程之间以及同一进程的不同线程之间的同步和互斥手段。

信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:
   (1) 测试控制该资源的信号量。
   (2) 若此信号量的值为正,则允许进行使用该资源。进程将信号量减1。
   (3) 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。
   (4) 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。
    维护信号量状态的是Linux内核操作系统而不是用户进程。我们可以从头文件/usr/src/linux/include /linux /sem.h 中看到内核用来维护信号量状态的各个结构的定义。信号量是一个数据集合,用户可以单独使用这一集合的每个元素。要调用的第一个函数是semget,用以获 得一个信号量ID。

    1. 套接口(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协议等

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
2
3
4
5
6
7
8
9
10
11
12
db1 数据库1
db2 数据库2
table1 数据表1
table2 数据表2

$spell = $this->SpellApply->table('db1.table1 t1,db2.table2 t2')
->field('t1.uid,t2.avatar_img')
->where('t1.uid=t2.uid and t1.spell_id ='.$id)
->order('t1.create_time desc')
->group('t1.uid')
->select();

Laravel5.5 使用仓库模式处理业务报表(多至34十张表)

人事和技术都过了,说要评估,然后没有然后了,

2018-08-29 广州伊思高

环境不适合,看了下就直接走了没有面试。

来自小鸡的面试题:

  1. array+array 和array_merge()的区别?
  2. 常见的网络攻击? 解决方案?

array+array 和array_merge()的区别?

  1. 当下标为数值时,array_merge()不会覆盖掉原来的值,但array+array合并数组则会把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉(不是覆盖).
  2. 当下标为字符时,array+array仍然把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉,但array_merge()此时会覆盖掉前面相同键名的值.

https://segmentfault.com/a/1190000009114383

常见的网络攻击? 解决方案?

XSS

XSS,Cross-site script,跨站脚本攻击。它可以分为两类:反射型和持久型。

  • 反射型XSS攻击场景:用户点击嵌入恶意脚本的链接,攻击者可以获取用户的cookie信息或密码等重要信息,进行恶性操作。
    • 解决:开启cookie的HttpOnly属性,禁止JavaScript脚本读取cookie信息
  • 持久型XSS攻击场景:攻击者提交含有恶意脚本的请求(通常使用<script>标签),此脚本被保存在数据库中。用户再次浏览页面,包含恶意脚本的页面会自动执行脚本,从而达到攻击效果。这种攻击常见于论坛,博客等应用中。
    • 解决:前端提交请求时,转义<&lt,转义>&gt;或者后台存储数据时进行特殊字符转义。
      建议后台处理,因为攻击者可以绕过前端页面,直接模拟请求,提交恶意

SQL注入

  • 攻击者在HTTP请求中注入恶意SQL命令,例如,drop table users,服务器用请求参数构造数据库SQL命令时,恶意SQL被执行。
    • 解决:后台处理,例如,使用预编译语句PreparedStatement进行预处理。

CSRF

CSRF,Cross-site request forgery,跨站请求伪造。这种方式是利用浏览器的cookie或服务器的session策略,盗取用户信息,模拟用户向第三方网站发送恶意请求。

  • 因为从WEB页面产生的所以请求,包括文件请求,都会带上cookie,这样,只要用户在网站A的会话还没有过期,访问恶意网站B时就可能被动发出请求到网站A,同时携带cookie信息,从而达到伪造用户进行恶性操作。
    • 解决方案:
    1. 提交请求中携带Token,并且每次请求的Token值都是合法的随机数。
      注意:使用时注意token的私密性,不要以url参数的形式发送(不要使用GET)。尽量采用POST操作,以form表单或者AJAX的形式提交。
    2. referer check:根据http request信息里面的referer参数(请求源),验证请求源是否合法。
      注意:某些情况下,浏览器不会发送referer参数,比如,从https跳转到http,为了安全性不会发送referer

https://www.jianshu.com/p/cacfe5749e81

按照osi七层协议,可以分为:

    1. 物理层 线路侦听
    1. 数据链路层 mac_flood
    1. 网络层 arp_poison,icmp_redirection
    1. 传输层 tcp_flood(包含ack_flood和syn_flood),udp_flood(ntp,dns)
    1. 应用层 connection_flood,http_get等等

按照攻击目的,可以分为:

    1. 中间人攻击(为了获得网络数据):mac_flood,arp_poison,icmp_redirection
    1. 拒绝服务攻击:tcp_flood,udp_flood,connection_flood,http_get

按照攻击者的位置,可以分为:

    1. 攻击者必须与攻击目标处于同一网段:mac_flood,arp_poison,icmp_redirection,线路侦听
    1. 不必处于同一网段:其他

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)

商城的核心模块?

  • 用户认证管理模块
  • 商品检索引擎模块
  • 广告管理与发布系统功能模块
  • 订单系统模块、购物车模块。

怎么实现购物车模块?未登录怎么加入购物车?实现未登录统计加入购物车的商品?

https://blog.csdn.net/qfikh/article/details/52943068

搜索商品名称,并跳转到商品页面,并且搜索关键字高亮显示

站内搜索结果怎么高亮显示关键字?

附笔试题

  1. $this,self,parent的区别?
  2. 命名空间有什么作用?
  3. JSON和JSONP的区别和注意细节?
  4. MVC分层是什么?TP5各自需要继承什么?
  5. trait功能是什么?
  6. TP5和TP3在控制器上的区别?
  7. TP参数绑定的定义和使用示例?

$this,self,parent的区别?

从字面上来理解,分别是指自己父亲。先初步解释一下,this是指向当前对象的指针(可以看成C里面的指针),self是指向当前类的指针,parent是指向父类的指针

  • $this是在实例化的时候来确定指向谁
  • self是指向类本身,也就是self是不指向任何已经实例化的对象,一般self使用来指向类中的静态变量
  • 使用parent来调用父类的构造函数

https://www.cnblogs.com/myjavawork/articles/1793664.html

命名空间有什么作用?

命名空间主要解决class类/function 函数/常量 等一些的命名冲突问题

官方命名空间概述

JSON和JSONP的区别和注意细节?

JSON

下面是jquery的ajax请求,数据类型为json,它是以json格式在前后台进行数据的传输,它与局限性就是不能跨域请求,这是为了网络数据的安全所制定的规则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$.ajax({
type: "post", // 数据提交类型
url: "danmu.php",// 请求地址 同源服务器/浏览器安全设置
data: {word:"abc",username:"ltt"}, // 发送数据
dataType: "json", // 返回数据的类型
async: true, // 是否异步,true为异步
// success为数据加载完成后的回调函数
success: function(data){
var show = document.getElementById('show');
for(i in data){
show.innerHTML += data[i]+"<br>";
}
console.log(data);
}
});

JSONP

大家都知道script标签是可以跨域请求的,jsonp的原理就是通过script的src,将函数作为src请求地址的参数来传递数据,所以jsonp只有get一种传输方式

下面是jsonp的数据交互,首先定义一个回调函数,定义dataType类型为jsonp,将函数作为参数传输给后台,它与json相比是多了一层函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript">
// 自定义的回调函数
function show(val){
document.getElementById("show").src=val[0].src;
}
$.ajax({
type:"get",
url:"myphp.php",
dataType:"jsonp", // 现在时jsonp请求,这个时候,jquery使用的是script标签发送请求
jsonp:"callmyphp", // 后台用来接受函数名的变量名
jsonpCallback:"show",// 自定义的回调函数名
async:true,
});

至于什么时候用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访问支持自动定位控制器;

Tp3.2和Tp5.0区别

TP参数绑定的定义和使用示例?

参数绑定是指绑定一个参数到预处理的SQL语句中的对应命名占位符或问号占位符指定的变量,并且可以提高SQL处理的效率,需要数据库驱动类的支持,目前只有PDO和Sqlsrv驱动支持参数绑定功能。
https://www.kancloud.cn/beyondzgz/tp/52559

手动绑定

参数手动绑定需要调用连贯操作的bind方法,例如:

1
2
3
$Model = M('User');
$where['name'] = ':name';
$list = $Model->where($where)->bind(':name',I('name'))->select();

自动绑定

对于某些操作的情况(例如模型的写入和更新方法),可以支持参数的自动绑定,例如:首先需要开启DB_BIND_PARAM配置参数:

1
2
3
4
$Model = M('User');
$Model->name = 'thinkphp';
$Model->email = 'thinkphp@qq.com';
$Model->add();

2018-08-30 广州众享

以下是我听过最智障的面试, 来自一位老年人程序员(至少35+,看上去)

你上家公司做什么,你负责什么,具体点。。。

你上上家公司做什么,你负责什么,具体点。。。

你上上家公司坐什么,你负责什么,具体点。。。

微信支付怎么做的, 具体流程说一下,具体点。。。

广州众享和广州微世纪是一起的,笔试题是一模一样的,然后还分别给了一份面试邀请。

2018-08-31 广州玩动网络(手趣网络、果玩网络)

面试让人很舒服,这个一定要说。
是做游戏的,需要对游戏相关有了解

Swoole的使用?除此之外别的PHP组件?

微服务?(RabbitMQ,Kafka,etcd,zookeeper)

Facades的作用?不是静态方法为何可以::调用

Facade其实是一个容器中类的静态代理,他可以让你以静态的方式来调用存放在容器中任何对象的任何方法。

Laravel 的 Facade 实现原理

依赖注入的原理?为什么可以这样做?

依赖注入(Dependency Injection)是用于实现控制反转(Inversion of Control)的最常见的方式之一
依赖注入原理(为什么需要依赖注入)

RPC协议?

英文原义:Remote Procedure Call Protocol
中文释义:(RFC-1831)远过程调用协议

MySQL索引优化,慢查询优化?

2018-08-31 广州天启互娱

附笔试题

  1. 的执行结果是?
  2. 使用list()函数需要注意什么?
  3. 请说明php_ini中safe_mode开启影响了哪些函数?
  4. 请对POSIX风格和兼容Prel风格正则主要函数类比说明?
  5. 简述PHP垃圾收集机制?
  6. php查询mysql数据库出现中文乱码解决方法?
  7. Session和Cookie的区别?
  8. 数据库优化?
  9. 如何处理负载和高并发?

请说明php_ini中safe_mode开启影响了哪些函数?

被安全模式限制或屏蔽的函数

2018-08-31 广州爱拍(不是本人面试)

爱拍面试在下周,这里记录一些爱拍的笔试题

  1. GET和POST的区别?
  2. 禁用Cookie后session是否可以正常使用,原理?
  3. 如何实现多机器Session共享?
  4. HTTP状态码1,2,3,4,5,6开头的分别什么意思?
  5. 阐述opcache原理?
  6. PHPTAL模板引擎,阐述原理
  7. 写出phpdocumentor 5个tags的名称及其含义?
  8. 简述对Symfony的了解?
  9. 简述Symfony中的announce路由原理?
  10. 最近看过的技术类书记有哪些?
  11. 写一个函数遍历目录?
  12. MySQL事务语句?
  13. Linux常见的shell有哪些?
  14. Linux下查看磁盘空间命令?
  15. 写清楚Linux命令统计/etc/passwd/文件下的每个组的人数
  16. 请简述进程和线程的区别?
  17. 编写一个Nginx的rewrite规则
  18. MYSQL有2000W数据,redis中只存20W数据,怎么保证redis都是热点数据?
  19. 写出HTTP工作过程步骤?

2018-09-03 广州港讯

公司环境很心水,公司团队不大,技术面试问的不深。

  1. Left Join, Right Join, Inner Join的区别?
  2. Left Join 时右表为空返回什么?怎么做条件判断?
  3. Redis的应用场景?(什么时候需要使用Redis)

Left Join, Right Join, Inner Join的区别?

  • left join(左联接): 返回包括左表中的所有记录和右表中联结字段相等的记录
  • right join(右联接): 返回包括右表中的所有记录和左表中联结字段相等的记录
  • inner join(等值连接): 只返回两个表中联结字段相等的行

Left Join 时右表为空返回什么?怎么做条件判断?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
A表
id aname
1 张三
2 李四

B表
id score aid bname year
1 90 1 语文 2018
2 92 1 数学 2019


select aname,bname,score from A left join B on A.id=B.aid where year='2018'


查询结果

张三 语文 90



select aname,bname,score from A left join B on A.id=B.aid and year='2018'

查询结果

张三 语文 90
李四 null null
  • 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尽量短,一般使用类名(表名)加主键拼接而成。
  • 选择一个优秀的序列化方式也很重要,目的是提高序列化的效率和减少内存占用。
  • 缓存内容与数据库的一致性,这里一般有两种做法:
    1. 只在数据库查询后将对象放入缓存,如果对象发生了修改或删除操作,直接清除对应缓存(或设为过期)。
    2. 在数据库新增和查询后将对象放入缓存,修改后更新缓存,删除后清除对应缓存(或设为过期)。

消息队列

Redis 中list的数据结构实现是双向链表,所以可以非常便捷的应用于消息队列(生产者 / 消费者模型)。消息的生产者只需要通过lpush将消息放入 list,消费者便可以通过rpop取出该消息,并且可以保证消息的有序性。如果需要实现带有优先级的消息队列也可以选择sorted set。而pub/sub功能也可以用作发布者 / 订阅者模型的消息。无论使用何种方式,由于 Redis 拥有持久化功能,也不需要担心由于服务器故障导致消息丢失的情况。

时间轴(Timeline)

list作为双向链表,不光可以作为队列使用。如果将它用作栈便可以成为一个公用的时间轴。当用户发完微博后,都通过lpush将它存放在一个 keyLATEST_WEIBOlist中,之后便可以通过lrange取出当前最新的微博。

下午复试,大致了解,前身是做外包的,所以还有挺多外包。项目较多,除五险一金无其他福利。

排行榜

使用sorted set和一个计算热度的算法便可以轻松打造一个热度排行榜,zrevrangebyscore可以得到以分数倒序排列的序列,zrank可以得到一个成员在该排行榜的位置(是分数正序排列时的位置,如果要获取倒序排列时的位置需要用zcard-zrank)。

计数器

计数功能应该是最适合 Redis 的使用场景之一了,因为它高频率读写的特征可以完全发挥 Redis 作为内存数据库的高效。在 Redis 的数据结构中,stringhashsorted set都提供了incr方法用于原子性的自增操作,下面举例说明一下它们各自的使用场景:

  • 如果应用需要显示每天的注册用户数,便可以使用string作为计数器,设定一个名为REGISTERED_COUNT_TODAYkey,并在初始化时给它设置一个到凌晨 0 点的过期时间,每当用户注册成功后便使用incr命令使该 key 增长 1,同时当每天凌晨 0 点后,这个计数器都会因为 key 过期使值清零。
  • 每条微博都有点赞数、评论数、转发数和浏览数四条属性,这时用hash进行计数会更好,将该计数器的 key 设为weibo:weibo_idhashfieldlike_numbercomment_numberforward_numberview_number,在对应操作后通过hincrby使hash 中的 field 自增。
  • 如果应用有一个发帖排行榜的功能,便选择sorted set吧,将集合的 key 设为POST_RANK。当用户发帖后,使用zincrby将该用户 idscore 增长 1sorted set会重新进行排序,用户所在排行榜的位置也就会得到实时的更新。

好友关系

对于一个用户 A,将它的关注和粉丝的用户 id 都存放在两个 set 中:

  • A:follow:存放 A 所有关注的用户 id
  • A:follower:存放 A 所有粉丝的用户 id

那么通过sinter命令便可以根据A:followA:follower的交集得到与 A 互相关注的用户。当 A 进入另一个用户 B 的主页后,A:followB:follow的交集便是 A 和 B 的共同专注A:followB: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,再通过前缀分词将这两个词分为若干个前缀索引,有:北京bbe…beijinbeijing。将这些索引分别作为setkey(例如:index:北)并存储北京的 id,倒排索引便建立好了。接下来只需要在搜索时通过关键词取出对应的set并得到其中的 id 即可。

一些建议

  • Redis 速度快是建立在内存数据库基础上的,但是一台服务器的内存要比磁盘金贵许多,所以在项目初期不要想什么都往 Redis 里放,这样当数据量上来后很快内存就会不够用,反而得不偿失。合理的利用有限的内存,将读(写)频繁的热数据放在 Redis 中才能更好感受到它带来的性能提升。
  • Redis 虽然提供了RDBAOF两种持久化方式,但是普遍还是认为 Redis 的持久化并不是很靠谱。这也是我一直不敢尝试彻底的用 Redis 去实现第五点(好友关系)的原因。

2018-09-03 广州深科信

与广州港讯在同一栋楼,24层,人事技术面试了快2个小时。回去等通知,然后说不合适。
技术聊了一个小时,大致围绕我原来的项目

技术问题:

  1. 购物车表设计?
  2. 高并发问题?

2018-09-04 广州米妍网研

  1. 从用户输入caoxl.com,到浏览器显示caoxl.com首页,经历了什么过程?
  2. 订餐系统?
  3. 美国上线,对接银联支付?

2018-09-04 广州量子云

真·初创公司,没有后端,服务器也没有,办公地点还可以,在万达广场18楼

  1. 图片库,图床?
  2. LBS(基于位置服务)?
  3. Redis实现热点数据?实现好友关系?
  4. PHP5和PHP7的垃圾回收机制?
  5. PHP7可选参数机制?
  6. IP协议,TCP协议,UDP协议的区别?
  7. 数据库引擎myisam和innodb的区别(至少5点)?
  8. 多进程和多线程的优缺点?
  9. strtr和str_replace的区别?
  10. $a=1,$b=$a,$a=2; 内存分配情况?
  11. 有哪些数据库锁?
  12. Redis是什么?Redis的数据类型有哪些?
  13. 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
2
3
USE 数据库名;
SHOW TABLES;
ALTER TABLE 表名 ENGINE=MYISAM;

修改MySQL数据库引擎为INNODB:

  1. 首先修改my.ini,在[mysqld]下加上:
1
default-storage-engine=INNODB
  1. 用sql语句修改已经建成表的引擎:
1
alter table 待改表名 type=InnoDB;

公司需求

  1. 理解SOA架构体系。
  2. 有实际的缓存(Redis/Memcache)、MQ(RabbitMQ/NSQ/RocketMQ)使用经验。
  3. 对MySQL集群,查询和索引优化有深入了解。
  4. 对主流内存及文件搜索引擎(ElasticSearch、Solr、Sphinx)使用和调优经验。
  5. 熟悉各类通讯协议(thrift、http、json)有socket编程经验。
  6. 熟悉分布式、高可用、高并发、可扩展性架构设计。

广州面对面F2F

  1. Swoole进程池?
  2. 索引的种类?区别?
  3. Redis怎么做队列?
  4. DDos攻击怎么解决?
  5. 身份伪造攻击怎么解决?
  6. TP5开发?
  7. myisam和innodb的区别?如何选择?
  8. 有那些队列组件?区别?

广州硅碳鼠

  1. 缓存技术?
  2. 关系型数据库和非关系型数据库区别?使用?
  3. 多进程和单进程的优缺点?
  4. 进程和异步的关系区别?
  5. Memcache和Redis的优缺点?使用场景?
  6. MySQL和MongoDB的区别?优缺点?
  7. 索引优化?索引选择?
  8. Linix下进程的交流?Nginx和Apache的优缺点?如何选择使用?

附录

Powered by Hexo and Hexo-theme-hiker

Copyright © 2017 - 2023 Keep It Simple And Stupid All Rights Reserved.

访客数 : | 访问量 :