优雅的代码注释

准确描述代码的行为。
代码分块,描述每一块的行为。

合理的变量命名

使用更具像化的词语描述,使别人不会误解。
对于返回是否的变量命名通过『is_』做前缀。

简化循环流程

条件语句中将常量放表达式右边。
避免使用 三目运算符、do/while 、goto 这些可读性比较差的结构。
把超长的表达式拆分成更容易理解的小块。
复杂表达式的等价转换写法,使可读性更高(德摩根定理)。
减少中间变量,减少中间变量的作用域。
积极的发现并抽取出不相关的子逻辑,是不是可以提取到公共方法或更高层;同时也要避免过度的拆分公共方法。
一次只做一件事,将你要做的事分成若干子步骤去处理。
『如果你不能把一件事解释给你祖母听的话说明你还没有真正理解它。』 —— 阿尔伯特 爱因斯坦

少写代码

一定程度上代码库越小越好,越轻量越好,这样你维护的成本会越小,主要是不要过度理解需求,以最方便的方式去解决问题,不要过度设计,因为你有时候很难去用到这些。
删除一些没用的代码。
熟悉你周边的库,每隔一段时间,花十几分钟来阅读标准库中的所有函数/模块/类型的名字。

测试的可读性

封装不重要的细节,使测试的重要细节更突出。
让错误消息具有可读性,将错误的输出打印出来。
合理的测试函数命名。
不要着迷于100%的测试覆盖率,参考2/8法则。
不要让测试成为产品开发的障碍。

总结

大概看了两周左右,将一些觉得比较好的内容总结了一下,并在实际工作中应用起来,之前一些不好的习惯在慢慢的刻意改正。书是本好书,经验与实例相结合,更容易读懂其中含义,让人品味到了坏代码的味道。这本书的内容还需要不断思考并实践。借用前辈告诫的一句话结尾『不要放任自己,要时刻保持严谨的态度,对代码负责,也是对自己负责。』

Mixin 是利用语言特性来简洁的实现组合模式,Python 中通过一定规范的多继承实现的。

使用时需要注意一下几点:

  • 类的单一职责
  • 对宿主类一无所知
  • 不存在对宿主类的方法调用,避免引入 MRO 查找顺序

如下例子,对于不同的 Mixin 类只负责实现自己的行为特征函数,然后 People 类继承这些特征,在自己的函数中使用这些特征。

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
#!/usr/bin/python
# coding: utf-8
"""
File: mixin_demo.py
Author: noogel <noogel@163.com>
Date: 2018-01-12 09:11
Description: mixin_demo
"""


class EatMixin(object):

def eat(self):
return "eat!"


class DrinkMixin(object):

def drink(self):
return "drink!"


class SleepMixin(object):

def sleep(self):
return "sleep!"


class People(EatMixin, DrinkMixin, SleepMixin):

def __init__(self):
print "People can ", self.eat()
print "People can ", self.drink()
print "People can ", self.sleep()


if __name__ == "__main__":
print "Init people."
people = People()

1
2
3
4
5
➜  dev-demo python mixin_demo.py 
Init people.
People can eat!
People can drink!
People can sleep!

https://www.zhihu.com/question/20778853

拿三台机器举例打洞配置讲解

机器 网络环境 用途 SSH服务
A机器 公网IP固定 中转机器 需要
B机器 NAT网络 被访问机器 需要
C机器 任意网络环境 需要访问B机器 不需要

自动连接重试

需要B机器向A机器建立 SSH 反向隧道,命令如下:

autossh -p 22 -M 6777 -NR '*:6766:127.0.0.1:22' usera@a.site

通过 autossh 可以实现连接失败自动重连,*:6766:127.0.0.1:22 是将A机器的6766端口转发到B机器的22端口,usera@a.site 是请求B机器的用户名和地址。

打洞

开启端口转发功能,编辑 sshd 的配置文件 /etc/ssh/sshd_config,增加配置:
GatewayPorts yes

另一台机器连接

通过C机器对A机器的6766端口发起连接就会自动被转发到B机器。

ssh -p 6766 userb@a.site

SSH 私钥认证

把请求机器的 ~/.ssh/id_rsa.pub 添加到被请求机器的 ~/.ssh/authorzied_keys 文件中

同时设置文件权限为 chmod 600 ~/.ssh/authorzied_keys

设置后在连接机器的时候就不需要密码了,可以走私钥认证。

守护进程

这里通过 supervisord 配置保证B机器重启后 autossh 能启动。

有固定公网IP的机器

这里我选用的是阿里云的机器,因为平时用的量不大,所以选择按量付费就可以了,看了下费用大概 80RMB/月。

参考:

http://blog.csdn.net/lidongshengajz/article/details/73482908
https://linux.cn/article-5975-1.html

安装samba

sudo apt-get install samba

添加用户

添加 smb 服务的用户名密码

sudo smbpasswd -a xyz

配置

编辑/etc/samba/smb.conf文件,在最后加上如下内容

1
2
3
4
5
6
7
[xyz]
comment = xyz's Home
path = /home/Doucument
browseable = yes
read only = no
guest ok = no
create mask = 0600

重启服务

sudo /etc/init.d/samba restart

交易系统设计与原则

墨菲定律

  1. 任何事都没有表面看起来那么简单。
  2. 所有的事都会比你预计的时间长。
  3. 会出错的事总会出错。
  4. 如果你担心某种情况发生,那么它就更有可能发生。

康威定律

  1. 组织沟通方式会通过系统设计表达出来。
  2. 时间再多一件事情也不可能做的完美,但总有时间做完一件事情。
  3. 线型系统和线型组织架构间有潜在的异质同态特性。
  4. 大的系统组织总是比小系统更倾向于分解。

https://yq.aliyun.com/articles/8611

高并发原则

  • 无状态 应用无状态,配置文件有状态。

  • 拆分 一个大而全的系统是按照功能模块拆分系统。

    • 系统维度:按照系统功能/业务拆分,比如商品系统、购物车、订单、支付、分账、结算等。
    • 功能维度:对一个系统进行功能拆分,优惠券创建系统、领券系统、用券系统。
    • 读写维度:使用读写分离,读服务考虑使用缓存提升性能,写服务量大可以考虑分库分表,聚合读取场景下考虑数据异构拆分系统然后将分散在多处的数据聚合到一处存储。
    • AOP 维度:面向切面编程,根据访问特征按照 AOP 进行拆分。处理日志记录,性能统计,安全控制,事务处理,异常处理等等。
    • 模块维度:按照基础模块特征进行拆分,比如分库分表、数据库连接池;代码结构按照三层划分。
  • 服务化 进程内服务 → 单机远程服务 → 集群手动注册服务 → 自动注册和服务发现 → 服务的分组/隔离/路由 → 服务治理。

  • 消息队列 使用消息队列可以实现服务解耦、异步处理、流量削峰/缓冲等。

    1. 大流量缓冲

    2. 数据校对:使用异步机制会存在消息丢失的情况,需要考虑定期去扫描原始表,对数据进行校对和问题的补偿。

  • 数据异构

    • 数据异构,比如订单分库分表,按照订单ID进行划分,对于异构意义不大不大的字段(库存价格)考虑异步加载,合并并发请求等。
    • 数据闭环,通过 MQ 机制接收数据变更,然后把原子化数据存储到合适的存储引擎,然后将数据聚合,把多个数据源拿过来,然后存储到KV存储中。如果一次需要多个数据,可以考虑使用 Hash Tag 机制将相关数据聚合到一个实例。
    • 前端展示,减少前端拿数据的数量。
  • 缓存银弹

    • 浏览器端缓存,通过设计过期时间进行控制,适用于不太敏感的数据。
    • APP 客户端缓存,为了防止瞬间流量冲击,把相关的静态文件下发到客户端缓存。
    • CDN 缓存,将一些活动页、图片、视频等资源推送到离用户进的 CDN 节点。一般是通过推送机制和拉取机制。
    • 接入层缓存,例如 Nginx 层,通过 URL 重写、一致性哈希、代理缓存等机制实现。
    • 应用层缓存
    • 分布式缓存
  • 并发化 将串行获取的数据通过并发化获取。

高可用原则

  • 降级 主要的是设计一个降级开关。
    • 开关集中化管理,通过推送机制将开关推送到各个应用。
    • 可降级的多级读服务,按照读写维度进行调用降级。
    • 开关前置化,将开关前置到 Nginx 接入层,对流量请求拦截或一小部分放流。
    • 业务降级,把同步调用改成异步调用,或者优先处理高优先级数据或包含特征的数据,合理分配流量进入系统,以保障系统可用。
  • 限流 为了防止恶意请求流量、恶意攻击,防止流量超出系统峰值。
    • 恶意请求只访问到 cache。
    • 穿透到后端的应用流量可以考虑使用 Nginx 层做处理。
    • 对于恶意 IP 使用 Nginx 层进行屏蔽。
    • 原则是限制流量穿透到后端薄弱的应用层。
  • 切流量 应对多机房环境某机房挂了或者机架挂了,或者不可抗拒的自然灾害,这时异地多活机房就很重要了。我们要做的就是能及时将异常的地方下线,流量切到正常的服务下。
    • DNS,切换机房入口。
    • LVS/HAProxy,切换故障的接入层。
    • Nginx,切换故障的应用层。
  • 可回滚 当服务出错时,通过版本话机制回滚到最近的一个正确版本。

业务设计原则

  • 防重设计,比如结算页面防止重复提交。
  • 幂等设计,在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。
  • 流程可定义,两个流程彼此分离,在需要的时候进行关联,或者复用一些理赔流程。
  • 状态与状态机,在设计交易订单系统,会存在正向状态和逆向状态,需要记录订单的状态轨迹并记录相关日志。还需要考虑并发状态修改的问题。
  • 后台系统操作的反馈,对后台系统操作场景能及时预览最终效果。
  • 后台系统审批,对于一些敏感操作记录日志,设计审批流程,保证操作可追溯、可审计。
  • 文档和注释,无需多说。
  • 备份,代码仓库的备份和管理。

调试面板

设置文件和代码模板

PyCharm comes with a set of predefined template variables.

The available predefined file template variables are:

${PROJECT_NAME} - the name of the current project.
${NAME} - the name of the new file which you specify in the New File dialog box during the file creation.
${USER} - the login name of the current user.
${DATE} - the current system date.
${TIME} - the current system time.
${YEAR} - the current year.
${MONTH} - the current month.
${DAY} - the current day of the month.
${HOUR} - the current hour.
${MINUTE} - the current minute.
${PRODUCT_NAME} - the name of the IDE in which the file will be created.
${MONTH_NAME_SHORT} - the first 3 letters of the month name. Example: Jan, Feb, etc.
${MONTH_NAME_FULL} - full name of a month. Example: January, February, etc.

官方文档 http://www.jetbrains.com/pycharm/help/creating-and-editing-file-templates.html

设置字体、字号

设置行号

  1. 临时设置。右键单击行号处,选择 Show Line Numbers。但是这种方法,只对一个文件有效,并且,重启PyCharm 后消失。

  2. 永久设置。File –> Settings –>Editor –>Appearance , 之后勾选Show Line Numbers。

开发环境配置

  1. 配置远程编译器,输入地址、用户名、密码、远程编译器路径,SSH方式连接。

  2. 调试配置。

  3. 配置远程开发环境项目目录。

  1. 设置自动上传

这篇文章主要记录可以提高效率和网络使用体验的优秀软件服务。

IFTTT

IFTTT 是一个网络自动化神器,目前是免费的,全称为 if this then that 。可以将你各种互联网服务之间的数据同步打通,例如社交、相册、云存储、笔记等等,一个例子是如果你印象笔记保存了一篇文章那么自动发送消息到你的邮箱,或者自动发送短信到指定号码;下雨天提醒你带伞;将你邮件中的附件自动备份到 Dropbox 上等等。

Dropbox

Dropbox 是一个云存储服务,通过云计算实现因特网上的文件同步,用户可以存储并共享文件和文件夹。它的有点主要感觉安全性上做的比较完善,可以和做内的一些企业云盘比肩,还有提供开放 API 可以给开发人员自由的发挥空间。缺点是在大陆被河蟹,你需要提个优质的 VPN 服务去使用。

MWeb


MWeb 是一款专业的 Markdown 写作、记笔记、静态博客生成软件。是一个个人开发者开发维护的,是 Apple 产品线上的 APP。主要特点是操作界面简单;功能强大,对于静态博客 Hexo、Jekyll 等的支持;方便导出各种格式;静态博客生成。功能比较强大,是目前博主遇到的支持的最好的 Markdown 编辑器。在 APP Store 收费 ¥98,值得这个价格。

MySQL 大小写区分问题

sql_mode 配置

Modes affect the SQL syntax MySQL supports and the data validation checks it performs. This makes it easier to use MySQL in different environments and to use MySQL together with other database servers.

查看当前sql_mode

1
2
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;

设置当前sql_mode

1
2
SET GLOBAL sql_mode = 'modes...';
SET SESSION sql_mode = 'modes...';

Full list of SQL Models

https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

/*!40001 SQL_NO_CACHE */

/*! */ 这是 mysql 里的语法,并非注释,! 后面是版本号,如果本数据库等于或大于此版本号,那么注释内的代码也会执行。

关于这个条件的问答: https://lists.mysql.com/mysql/203373

iTerm

重置配置命令:
defaults delete com.googlecode.iterm2
水平分屏:
command + d
垂直分屏:
command + shift + d

Tmux

https://github.com/gpakosz/.tmux

新建会话:tmux new -s dev
连接会话:tmux a -t dev
列出所有会话:tmux ls
新建窗口:tmux new -n abc
prex : ctrl + b
切换 pane : prex + o
关闭 pane : prex + x
新建水平 pane : prex + "
新建垂直 pane : prex + %
copy-mode : prex + [

Chrome

刷新页面 : command + r
打开关闭控制台 : command + option + j
打开最近关闭的页面 : shift + command + t
MacOS 局域截屏 : command + shift + 4  

PyCharm

格式化 : command + option + L
光标向前 : command + [
光标向后 : command + ]
上下文对象命名修改 : Shift + F6

Sublime Text 3

选中所有 Command + Ctrl + G

Linux

随机采样命令: shuf -n 100 file.txt