某上市公司一面二面

1.tcp与udp的区别

tcp 面向连接的,提供可靠的基于字节流的传输协议

udp 非面向连接的不可靠的传输协议

2.简述TCP的三次握手过程

TCP握手协议

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

SYN:同步序列编号(Synchronize Sequence Numbers)

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手.

完成三次握手,客户端与服务器开始传送数据

手写常用的设计模式

/**
 * Class single
 * 单利模式
 * 单例模式可以有效避免不同程序员new自己的对象,造成人为的系统消耗
 */
final class single
{
    private static $obj;
    private function __construct(){
 
    }
    private function __clone(){
 
    }
    public static function getObj(){
        if(self::$obj){
           return  self::$obj;
        }
        return self::$obj = new self();
    }
}
//$obj = single::getObj();
//print_r($obj);
/**
 * Interface person
 * 工厂模式
 * 解决的是如何不通过new建立实例对象的方法
 * 目的是可以随意改类名,而外面调用的是工厂里面的方法,所以以后维护的时候只需要改简单的几个类名就行
 */
interface person
{
    function eat();
}
class woman implements person
{
    function eat(){
        echo 1;
    }
}
class man implements person
{
    function eat(){
        echo 2;
    }
}
class plant
{
    public static function factory($obj){
        switch ($obj) {
            case 'woman':
                return new woman();
                break;
 
            case 'man':
                return new man();
                break;
        }
    }
}
//$obj = plant::factory('man');
//$obj -> eat();
 
/**
 * Class register
 * 注册树
 * 统筹管理安排一些类,降低我们依赖关系模块的耦合度
 *
 */
class register
{
    private static $objs;
    public static function set($name,$obj){
        self::$objs[$name] = $obj;
    }
    public static function get($name){
        return self::$objs[$name];
    }
    public static function del($name){
        unset(self::$objs[$name]);
    }
}
//register::set('a',plant::factory('man'));
//$obj = register::get('a');
//$obj -> eat();
 
/**
 * Interface IDatabase
 * 适配器模式
 * 将各种截然不同的函数接口封装成统一的API。
 * PHP中的数据库操作有MySQL,MySQLi,PDO三种,可以用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。
 * 类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。
 * 首先定义一个接口(有几个方法,以及相应的参数)。然后,有几种不同的情况,就写几个类实现该接口。将完成相似功能的函数,统一成一致的方法。
 */
interface IDatabase
{
    function connect($host, $user, $passwd, $dbname);
    function query($sql);
    function close();
}
 
class MySQL implements IDatabase
{
    protected $conn;
    function connect($host, $user, $passwd, $dbname)
    {
        $conn = mysql_connect($host, $user, $passwd);
        mysql_select_db($dbname, $conn);
        $this->conn = $conn;
    }
    function query($sql)
    {
        $res = mysql_query($sql, $this->conn);
        return $res;
    }
    function close()
    {
        mysql_close($this->conn);
    }
}
 
class _MySQLi implements IDatabase
{
    protected $conn;
    function connect($host, $user, $passwd, $dbname)
    {
        $conn = mysqli_connect($host, $user, $passwd, $dbname);
        $this->conn = $conn;
    }
    function query($sql)
    {
        return mysqli_query($this->conn, $sql);
    }
    function close()
    {
        mysqli_close($this->conn);
    }
}
/**
 * Class Event
 * 观察者模式
 * 当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新。
 * 场景:一个事件发生后,要执行一连串更新操作.传统的编程方式,就是在事件的代码之后直接加入处理逻辑,
 * 当更新得逻辑增多之后,代码会变得难以维护。.这种方式是耦合的,侵入式的,增加新的逻辑需要改变事件主题的代码
 * 观察者模式实现了低耦合,非侵入式的通知与更新机制
 */
class Event
{
    private static $objs = [];
    public function  addObj($obj){
        $this->objs[] = $obj;
    }
    public function notify(){
        foreach ($this->objs as $v ){
             $v -> update();
        }
    }
}
interface ServerObj{
    function update();
}
class Obj1 implements ServerObj
{
    function update(){
        echo  'obj1';
    }
}
class Obj2 implements ServerObj
{
    function update(){
        echo  'obj2';
    }
}
class TrigEvent extends Event
{
    function trigger(){
        return $this -> notify();
    }
}
$event = new TrigEvent;
$event -> addObj(new Obj1);
$event -> addObj(new Obj2);
$event -> trigger();
<?php
$a = '1';
$b = &$a;
$b = "2$b";
$c = ++$b;
$d = ($c > $b) ? $b : $c;

var_dump(implode(',', [$a, $b, $c, $d]));

结果是:string(11) “22,22,22,22”

注意是var_dump(),严谨点结果是要有string(11),直接写22,22,22,22也行,我相信面试官是不会计较这个

5.nginx的错误日志error.log中报alert :accept() error,Too many open file,请分析这个是什么错。

这个我当时留空了,不会。

上网查了下,可以看看机器的系统配置 ulimit -a

列出的open_files:1024,代表单进程最大文件描述符限制了1024个,

所以上面的报错是这里导致的。

6.mysql的四种隔离级别及其之间的层次关系

1.未提交读,读已提交,可重复度,可串行化

7.ls -lhi 命令在控制台中输出如下

930495 drwxr-xr-x 3 root root 4.0K Apr 14 18:00 agent_tracker
930457 drwxr-xr-x 3 root root 4.0K Mar 26 10:13 frp
930497 -rw-r--r-- 1 root root 182K Mar 26 11:42 frp.git
930255 -rw------- 1 root root    0 Mar 26 17:49 nohup.out
930525 drwxr-xr-x 2 root root 4.0K Apr 15 10:24 redis-cell
930498 drwxr-xr-x 3 root root 4.0K Apr 10 10:50 script

ls -lhi 文件(查看文件详情 权限信息)

[root@iZwz9exe2jul8fc4gtaydyZ ~]# ls -lhi frp
total 7.7M
930487 drwxrwxrwx 2 www  www  4.0K May 11 00:00 frp_0.25.0_linux_amd64
930486 -rw-r--r-- 1 root root 7.7M Mar 11  2019 frp_0.25.0_linux_amd64.tar.gz

8.myisam与innodb的索引结构

b tree 和b+ tree

9.什么情况下产生行锁,什么情况下产生表锁

innodb才支持行锁,条件字段用到索引了就会产生行锁,没有用到索引就会表锁

mysiam是只支持表锁,没有行锁。

10.单点登录的原理 是指在多系统应用群中登录一个系统,便可在其他所有系统中得到授权而无需再次登录,包括单点登录与单点注销两部分

11.秒杀系统如果保证高并发,并且如何实现库存

秒杀开启时redis中保存了各商品对应的库存,Redis decr 如果小于0,说明商品已经卖完了,此次秒杀无效,并且设置该商品的内存标识为true,表示已卖完;

12.redis的两种数据持久策略及各自优缺点

RDB的优点:

1.RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集

2.RDB 非常适用于灾难恢复

3.RDB 可以最大化 Redis 的性能

RDB的缺点:

1.如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。

2.每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 数据集比较大请求好耗时长的情况下,fork()可能会非常耗时,造成服务器在某某毫秒内停止处理客户端

AOF 的优点:

1.使用 AOF 持久化会让 Redis 变得非常耐久

2.AOF 文件是一个只进行追加操作的日志文件

3.Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写

4.AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松

AOF 的缺点:

1.对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。

2.根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB

3.AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样

13.webserver + php-fpm 的cpu load 和 连接数飙高,mysql的cpu load和连接数也飙高,请你说出可能造成改问题的原因及解决方案。

1、找出占用CPU最高的10个进程 ps aux | sort -k3nr | head -n 10

或查看占用内存最高的10个进程

ps aux | sort -k4nr | head -n 10  

或者使用 top ,按 1 显示CPU列表,再按 shift+p 以CPU排序

top

mysql 连接数查看 show status like 'Threads%';

查询数据库当前设置的最大连接数 show variables like '%max_connections%';

跟踪线程

当MySQL繁忙的时候运行show processlist,会发现有很多行输出,每行输出对应一个MySQL连接。怎么诊断发起连接的进程是哪个?它当前正在干嘛呢?

show processlist;

netstat -ntp | grep 端口

解决方案:

1.设置控制php-fpm进程池进程数量。

2.开启慢日志。

3.内存分配。

4.编辑php-fpm.conf配置文件(php_admin_value[memory_limit] = 128M)

写脚本监听cpu超过九十监听那个进程造成的

大海技术博客
请先登录后发表评论
  • latest comments
  • 总共0条评论