tmux使用

基本使用

<prefix>$可以重命名当前Session
<prefix>c可以创建新的窗口(Window)
<prefix>%水平分割窗口(形成两个Pane)
<prefix>"垂直分割窗口。退出当前Session的快捷键是<prefix>d

在Bash中可以查看当前的tmux服务中有哪些Session:tmux ls
根据Session的名字可以再回去:tmux a -t myname (or at, or attach)

基本配置

默认的<prefix>Ctrl+b,如果觉得不好按可以调整为Ctrl+a,只需要在配置文件~/.tmux.conf中加入:

1
2
unbind ^b
set -g prefix 'C-a'

为了能让Tmux动态载入配置而不是重启,我们设一个快捷键r来重新载入配置:

1
bind r source-file ~/.tmux.conf \; display-message "Config reloaded"

当前tmux的设置,可通过tmux show -g

窗格切换

可以把hjkl设置为切换窗格的快捷键:

1
2
3
4
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

再给调整窗格大小设置快捷键:

1
2
3
4
bind L resize-pane -L 10 # 向左扩展
bind R resize-pane -R 10 # 向右扩展
bind K resize-pane -U 5 # 向上扩展
bind J resize-pane -D 5 # 向下扩展

php中的坑

路径的坑

$path = ‘/a/m/../b’;
假如 /a 存在
不管 /a/m 目录存不存在, mkdir 都能成功
但是如果不存在,那么 is_dir, realpath 等函数都会失败

计算的坑

1
2
3
4
5
6
7
$a = 5.1;
$b = 5.1;
$size = 100;
$t1 = intval($a = floatval($a) * $size);
$t2 = intval($b = floatval($b) * $size);
$t = rand($t1, $t2);
echo $t; // 计算结果是509,而不是510

图片资源优化

  1. 选择合适的图片格式

    原理:对图片格式转换,在画质可以接受的情况下达到更好的压缩比效果
    优势:减少图片加载流量,效果比较明显
    劣势:服务器和浏览器压力增大,而且服务器需要额外的服务支持,格式转换要考虑浏览器的兼容性

  2. 图片大小小于2KB时可使用base64编码代替图片

  3. 不同终端对同一个图片需求不一样,可以根据终端加载不同的图片来节省没必要的流量

  4. 使用css、svg、canvas或iconfont代替图片

  5. 合并图片:

    优势:可以有效的较少请求个数
    劣势:生成的图片体积较大,减少请求个数同时也增加了图片大小,不合理拆分将不利于并行加载

  6. 图片压缩

    原理:对图片进行无损、有损压缩,转为压缩后图片来实现
    优势:减少图片加载流量,效果比较明显
    劣势:服务器和浏览器压力增大,而且服务器需要额外的服务支持

  7. 使用 CDN

    使用参数自动调节图片质量和大小的,最关键的还是,CDN 的每 G 流量价格普遍比 VPS 按流量付费的价格要低得多!

  8. 部署到单独的服务器中

设计模式

3种基本设计模式

  1. 工厂模式,工厂方法或者类生成对象,而不是在代码中直接new
  2. 单例模式,使某个类的对象仅允许创建一个
  3. 注册模式,全局共享和交换对象

代理模式

  1. 在客户端与实体之间建立一个代理对象(proxy),客户端对实体进行操作全部委派给代理对象,隐藏实体的具体实现细节
  2. proxy还可以与业务代码分离,部署到另外的服务器。业务代码中通过RPC来委派任务

迭代器模式

  1. 在不需要了解内部实现的前提下,遍历一个聚合对象的内部元素
  2. 相比于传统的编程模式,迭代器模式可以隐藏遍历元素的所需的操作

装饰器模式

  1. 可以动态的添加修改类的功能
  2. 一个类提供了一项功能,如果要修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重新实现类的方法
  3. 使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性

观察者模式

  1. 当一个对象状态发生改变时,依赖它的对象全部会受到通知,并自动更新
  2. 场景: 一个事件发生后,要执行一连串更新操作。传统的编程方式就是在事件的代码之后直接加入处理逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件主体的代码
  3. 观察者模式实现了低耦合,非侵入的通知和更新机制

高级 PHP

面向对象5原则

单一职责原则(single-resposibility principle)

其核心思想为:一个类,最好只做一件事,只有一个引起它的变化的原因

开放-封闭原则(The Open-Close principle)

其核心思想为:对扩展开放,对修改封闭
软件实体(类、模块、函数)应该是可扩展的,但是不可修改的。也就是说,对于扩展是开放的,对于更改是封闭的。怎样可能在不改动模块源代码的情况下去更改它的行为呢?怎样才能在无需对模块进行改动的情况下改变它的功能呢?关键是抽象!因此在进行面向对象设计时要尽量考虑接口封装机制、抽象机制和多态技术。该原则同样适合于非面向对象的方法,是软件工程设计方法的重要原则之一

Liskov 替换原则(liskov-substitution principle)

其核心思想:子类必须能够替换其基类
子类应当可以替换父类出现在父类能够出现的任何地方

依赖倒置原则(dependency-inversion principle)

其核心思想:依赖于抽象
一个类不应该强依赖另外一个类,每个类对于另外一个类都是可替换的
1、高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
2、抽象不应该依赖于细节。细节应该依赖于抽象。在进行业务设计时,于特定业务有关的依赖关系应该尽量依赖接口和抽象类,而不是依赖于具体类。具体类只负责相关业务的实现,修改具体类不影响与特定业务有关的依赖关系。

接口分离原则(interface-segregation principle)

linux相关操作

防火墙

关闭防火墙

/etc/init.d/iptables stop
service iptables stop # 停止服务

查看防火墙信息

/etc/init.d/iptables status

开放端口:8080

/sbin/iptables -I INPUT -p tcp –dport 8080 -j ACCEPT

重启防火墙以便改动生效:(或者直接重启系统)

/etc/init.d/iptables restart

将更改进行保存

通过网址自动部署web

  1. 部署代码至单独的web站点
    https://github.com/markomarkovic/simple-php-git-deploy.git
  2. 配置www-data用户
    /usr/sbin/nologin=>/bin/bash,且可找到www-data用户的目录:/var/www
  3. 设置www-data登录密码
    sudo passwd www-data
  4. 设置/var/www归属
    sudo chown -R www-data:www-data /var/www/
  5. 切换到www-data用户
    su /var/www
  6. /var/www/.ssh目录中生成ssh key
    sudo -Hu www-data ssh-keygen -t rsa -C “entimm@gmail.com”
  7. 登录git托管网址,把id_rsa.pub公约贴上去
  8. 设置webhook

很有用的一些技巧

在利用 xdebug 和 phpstorm 调试通过终端执行的 PHP 脚本时,在终端执行先语句,即可对该脚本进行调试

1
export XDEBUG_CONFIG = "idekey=PHPSTORM"

通过SSH方式登录远程服务器时,通过下面方式免除每次都要输入密码

1
2
3
4
5
6
7
8
9
10
11
12
# 先在本机生成 authentication keys,注意不能输入 passphrase
# 这里假设 A 是本机,B是远端
a@A:~> ssh-keygen -t rsa
# 然后登录 B,并建立一个目录 ~/.ssh
a@A:~> ssh b@B mkdir -p .ssh
# 最后把 A 的 id_rsa.pub 追加到 B 的 ~/.ssh/authorized_keys 中去
a@A:~> cat ~/.ssh/id_rsa.pub | ssh b@B 'cat >> ~/.ssh/authorized_keys'
# 然后就成功了
a@A:~> ssh b@B

使用的 PHP 的内建服务器

1
php -S 主机名或地址@端口号 -t 目录

svn 检出当前目前下的文件或文件名,这在开发过程中不想检出全部数据时很有用

1
svn update --set-depth immediates

git 新建一个全新的空白分支

1
2
git checkout --orphan 分支名
git clean -f

面试问题总结

php魔术方法(14项)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
__construct() 实例化类时自动调用.
__destruct() 类对象使用结束时自动调用.
__set() 在给未定义的属性赋值的时候调用.
__get() 调用未定义的属性时候调用.
__isset() 使用isset()或empty()函数时候会调用.
__unset() 使用unset()时候会调用.
__sleep() 使用serialize序列化时候调用.
__wakeup() 使用unserialize反序列化的时候调用.
__call() 调用一个不存在的方法的时候调用.
__callStatic()调用一个不存在的静态方法是调用.
__toString() 把对象转换成字符串的时候会调用.比如 echo.
__invoke() 当尝试把对象当方法调用时调用.
__set_state() 当使用var_export()函数时候调用.接受一个数组参数.
__clone() 当使用clone复制一个对象时候调用.

HTTP协议中几个状态码的含义.

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
200 OK 正常返回信息
201 Created 请求成功并且服务器创建了新的资源
202 Accepted 服务器已接受请求,但尚未处理
301 Moved Permanently 请求的网页已永久移动到新位置.
302 Found 临时性重定向.
303 See Other 临时性重定向,且总是使用 GET 请求新的 URI.
304 Not Modified 自从上次请求后,请求的网页未修改过.
400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求.
401 Unauthorized 请求未授权.
403 Forbidden 禁止访问.
404 Not Found 找不到如何与 URI 相匹配的资源.
500 Internal Server Error 最常见的服务器端错误.
503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护).
100 Continue
101 Switching Protocols
200 OK
201 Created
202 Accepted
203 Non-Authoritative Information
204 No Content
205 Reset Content
206 Partial Content
300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
305 Use Proxy
307 Temporary Redirect
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Time-out
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Request Entity Too Large
414 Request-URI Too Large
415 Unsupported Media Type
416 Requested range not satisfiable
417 Expectation Failed
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Time-out
505 HTTP Version not supported

语句include和require的区别

在失败的时候:
include 产生一个 warning ,而 require 直接产生错误中断;

require 在运行前载入;
include 在运行时载入;

require_onceinclude_once 可以避免重复包含同一文件.

如果网站框架的设计能避免重复引用的话,推荐用include/require,
因为他们比_once速度稍快.

事务的特征(ACID)

面试可能会被问到的问题

抽象 vs 接口

抽象类是一种不能被实例化的类,只能作为其他类的父类来使用。
抽象类是通过关键字 abstract 来声明的。
抽象类与普通类相似,都包含成员变量和成员方法,两者的区别在于,抽象类中至少要包含一个抽象方法,
抽象方法没有方法体,该方法天生就是要被子类重写的。
抽象方法的格式为:abstract function abstractMethod();

因为php中只支持单继承,如果想实现多重继承,就要使用接口。也就是说子类可以实现多个接口。
接口是通过interface关键字来声明的,接口中的成员常量和方法都是public的,方法可以不写关键字public,
接口中的方法也是没有方法体。接口中的方法也天生就是要被子类实现的。

抽象类和接口实现的功能十分相似,最大的不同是接口能实现多继承。在应用中选择抽象类还是接口要看具体实现。
子类继承抽象类使用extends,子类实现接口使用implements。

文件上传注意事项

  1. 首现要在php.ini中开启文件上传;
  2. 在php.ini中有一个允许上传的最大值,默认是2MB。必要的时候可以更改;
  3. 上传表单一定要记住在form标签中写上enctype=”multipart/form-data”;

cookie作用

  1. 记录用户访问的部分信息
  2. 在页面间传递变量

php 的数据类型

php支持8种原始数据类型。
包括:
四种标量类型(布尔型boolean,整型interger,浮点型float/double , 字符串string)
两种复合类型(数组array , 对象object)
两种特殊类型(资源resource,NULL)