134 |
135 | I have a nice subtle inner rounding, don’t I look pretty?
136 |
137 |
138 | ```
139 |
140 | 用了两种方式实现边框内圆角
141 |
142 | 第一种方式用
143 |
144 | outline画外部的灰色边框
145 |
146 | 然后内部用圆角
147 |
148 | 但是会有一些间隙
149 |
150 | 用box-shadow填补
151 |
152 | 那么box-shadow应该设置多少了
153 |
154 | 现在我们的border-radio设置的是.8em 表明 是个正圆
155 |
156 | 所以边长一致, 圆心到描边角的距离为 开根号(0.8^2 + 0.8^2) 所以box-shadow 应该是 开根号(2 * (0.8^2) ) - 0.8
157 |
158 | 总结公式可为 r(根号2 - 1) 因为根号2-1 < 0.5 也可以偷懒设置为0.5 所以就是0.5 * r (r即为border-radius)
159 |
160 | 该公式也暴露了一个问题 box-shadow需要比outline宽度小, 并且 扩张半径要比(根号2 -1)r要大 才能进行填充
161 |
162 | 第二种方式就比较简单了不多说明了
163 |
164 | ## 2.5 条纹背景
165 |
166 | ```html
167 | 如果多个色标具有相同的位置, 他们会产生一个无限小的过渡区域,
168 |
169 | 过渡的起止色分别是 第一个和最右一个指定值, 从效果上看 颜色会在那个位置突然变化
170 |
171 | 而不是一个平滑的剪标过程
172 | ```
173 |
174 | ```html
175 | 如果某个色标的位置值比整个列表中在它之前的色标位置值都要小
176 |
177 | 则该色标的位置值会被设置为它前面所有色标位置值的最大值
178 | ```
179 |
180 | # 5. 字体排印
181 |
182 | # 7. 结构和布局
183 |
184 | ## 7.38 根据兄弟元素的数量来设置样式
185 |
186 | 想当列表中子元素的个数为4个的时候设置元素
187 |
188 | ```css
189 | li:first-child:nth-last-child(4), /* 匹配第一个元素 并且是倒数第4个元素 那就是li元素只有4个情况才能匹配上*/
190 | li:first-child:nth-last-child(4) ~ li /* 取到第一个元素然后向后取兄弟节点*/
191 | { }
192 |
193 | ```
194 |
195 | 做成通用的scss就是
196 |
197 | ```css
198 | @mixin n-items($n){
199 | &:first-child:nth-last-child(#{$n}),
200 | &:first-child:nth-last-child(#{$n} ~ &) {
201 | @content;
202 | }
203 | }
204 |
205 | /* 调用时 */
206 | li {
207 | @include n-items(4){
208 | xxx
209 | }
210 | }
211 | ```
212 |
213 | 当想匹配到元素大于等于4个时 样式为A
214 |
215 | ```css
216 | li:first-child:nth-last-child(n+4),
217 | li:first-child:nth-last-child(n+4) ~ li { A }
218 | ```
219 |
220 | 当想匹配元素小于等于4个时样式为B
221 |
222 | ```css
223 | li:first-child:nth-last-child(-n+4),
224 | li:first-child:nth-last-child(-n+4) ~ li { B }
225 | ```
226 |
227 | # DEMO
228 |
229 | http://play.csssecrets.io/
--------------------------------------------------------------------------------
/da_xing_wang_zhan_ji_zhu_jia_gou_he_xin_yuan_li_yu.md:
--------------------------------------------------------------------------------
1 | # 大型网站技术架构核心原理与案
2 |
3 | # 1. 大型网站架构演化
4 |
5 | ## 1.4 网络架构设计误区
6 |
7 | ### 1.4.3 企图用技术解决所有问题
8 |
9 | 12306在2013年抢票为秒杀模式,这种几亿人一票难求的情况下仍然用秒杀模式,无法从技术水平上解决
10 |
11 | 从业务方面下手,购票改为分时段售票.
12 |
13 | # 2. 大型网站架构模式
14 |
15 | 建筑学的模式: 每一个模式描述一个在我们周围不断重复发生的问题以及该问题解决方案的核心.这样,你就能一次又一次地使用该方案而不必重复工作
16 |
17 | ## 2.1 网站架构模式
18 |
19 | ### 2.1.1 分层
20 |
21 | 横向切分
22 |
23 | 1. 应用层: 视图和业务展示
24 | 2. 服务层: 为应用层提供服务支持
25 | 3. 数据层: 提供数据存储访问服务
26 |
27 | 分层最初为了规划软件清晰的逻辑结构,但分层结构对高并发分布式方向发展至关重要
28 |
29 | ### 2.1.2 分割
30 |
31 | 比如在应用层,将不同业务进行分割
32 |
33 | ### 2.1.3 分布式
34 |
35 | 对于大型网站,分层和分割的其中一个目的是为了切分后的模块便于分布式部署
36 |
37 | ### 2.1.4 集群
38 |
39 | 即使访问量很少的分布式应用和服务,也至少要部署两台服务器构成一个小的集群
40 |
41 | ### 2.1.5 缓存
42 |
43 | ### 2.1.6 异步
44 |
45 | 服务器可以通过多线程共享内存队列来实现异步
46 |
47 | ### 2.1.7 冗余
48 |
49 | 服务器可能出现故障,某台服务器down掉是必然事件.
50 |
51 | 要想保住服务器宕机情况下网站一人可以继续服务,不丢失数据,就需要一定程度的服务器冗余进行,数据冗余备份
52 |
53 | 访问和负载很小也必须至少部署两台服务器构成一个集群
54 |
55 | 数据库除了定期备份,存档保存,实现冷备份外,为了保证业务高可用,还需要数据库主从分离,实时同步实现热备份
56 |
57 | 为了抵御地震,海啸,还需要全球范围内部署灾备数据中心
58 |
59 | ### 2.1.8 自动化
60 |
61 | 1. 自动化代码管理: 代码版本控制、代码分支创建合并等过程自动化(打tag可以自动化,但是代码分支创建合并自动化????)
62 | 2. 自动化测试: 自动化测试并发测试报告
63 | 3. 自动化部署: 将工程代码自动部署到线上生产环境(简单理解为一键部署吧?)
64 | 4. 自动化安全检测: 安全检查工具对代码进行静态安全扫描及部署到安全测试环境进行安全攻击测试,评估其安全性.
65 | 5. 自动化监控: 对服务器进行心跳检测,对各项性能指标和应用程序的关键数据指标.
66 | 6. 自动化失效转移: 监控到有问题的服务器,自动移除出集群
67 | 7. 自动化失效恢复: 故障消除后,自动失效恢复
68 | 8. 自动化降级: 当网站到达高峰时,关闭不重要和耗时的功能,保证整个系统安全可用
69 | 9. 自动化分配资源: 必要时,还需要自动化分配资源,将空闲资源给配给重要的服务
70 | 10. 自动化性能测试: 发布部署时,可以对前端模拟加载时间和访问接口自动进行压测(笔者自己加的)
71 |
72 | ### 2.1.9 安全
73 |
74 | 1. 通信家吗
75 | 2. XSS SQL注入防范
76 |
77 | # 3 大型网站核心架构要素
78 |
79 | 架构: 最高层次的规划,难以改变的决定
80 |
81 | ## 3.1 性能
82 |
83 | 性能只是必要条件,指标有响应时间,TPS,系统性能计数器
84 |
85 | ## 3.2 可用性
86 |
87 | 网站高可用的主要手段是冗余
88 |
89 | ## 3.3 伸缩性
90 |
91 | 应用服务器,只要服务器不保存服务器,所有服务器偶读对等
92 |
93 | 缓存服务器,加入新服务器可能会导致缓存路由失效,可能会导致系统GG
94 |
95 | 关系数据库的伸缩性方案必须在数据库之外实现,通过路由分区等手段将部署有多个数据库的服务器组成一个集群
96 |
97 | 而大部分NoSQL是天生支持伸缩的
98 |
99 | ## 3.4 拓展性
100 |
101 | 如何设计网站的架构能快速响应业务变化,是可拓展的主要目的
102 |
103 | ## 3.5 安全性
104 |
105 | # 4 瞬时响应: 网站高性能架构
106 |
107 | ## 4.1 网站性能测试
108 |
109 | ### 4.1.2 性能测试指标
110 |
111 | >响应时间
112 |
113 | 一般的响应时间表
114 |
115 | 1. 打开一个网站: 几秒
116 | 2. 在数据库查找有索引的记录: 十几毫秒
117 | 3. 机械磁盘一次寻址定位: 4毫秒
118 | 4. 从机械磁盘顺序读取1MB数据: 2毫秒
119 | 5. 从SSD顺序读取1MB数据: 0.3毫秒
120 | 6. 从远程分布式缓存Redis读取一个数据: 0.5毫秒
121 | 7. 从内存中读取1MB数据: 十几微秒
122 | 8. Java本地方法调用: 几毫秒
123 | 9. 网络传输2KB数据: 1微秒
124 |
125 | >并发数
126 |
127 | 指系统能够同时处理请求的数目
128 |
129 | > 吞吐量
130 |
131 | 指单位时间内系统处理的请求数量
132 |
133 | 1. TPS: 每秒事务数
134 | 2. HPS: 每秒HTTP请求数
135 | 3. QPS: 每秒查询数
136 |
137 | > 性能计数器
138 |
139 | 主要是top的指标
140 |
141 | ## 4.3 应用服务器性能优化
142 |
143 | ### 4.3.4 代码优化
144 |
145 | >多线程
146 |
147 | 启动线程数 = [任务执行时间/(任务执行时间-IO等待时间)] X CPU内核数
148 |
149 | 注意线程安全问题
150 |
151 | 1. 将对象设计为无状态对象: 对象本身不存储状态信息(对象无成员变量或者成员变量也是无状态对象)
152 | 2. 使用局部变量: 除非故意的把对象传给其他线程
153 | 3. 并发访问资源时加使用锁:
154 |
155 | > 资源复用
156 |
157 | 1. 单例
158 | 2. 对象池
159 |
160 | # 5 万无一失: 网站的高可用架构
161 |
162 | # 6 永无止境: 网站的伸缩性架构
163 |
164 | ## 6.3 分布式缓存集群的伸缩性设计
165 |
166 | ### 6.3.2 Memcached分布式缓存集群的伸缩性挑战
167 |
168 | 简单的路由算法可以用余数Hash
169 |
170 | 用服务器数目除缓存数据KEY的Hash值
171 |
172 | 余数为服务器列表的下标编号
173 |
174 | 如果不考虑服务器集群的伸缩性,余数Hash几乎可以满足绝大多数缓存路由需求
175 |
176 | 但是
177 |
178 | 假如由于业务发展网站从三台缓存服务器扩容到四台
179 |
180 | 那么大概会有3/4被缓存的数据不能被命中
181 |
182 | 所以这种扩容抖好一般都要在访问量比较少时j进行(例如半夜)
183 |
184 | 假如在100台服务器中加入一台服务器,不能命中的概率为99%
185 |
186 | ### 6.3.3 分布式缓存的异质性Hash算法
187 |
188 | 一致性Hash算法通过一个叫做一致性Hash环的数据结构实现KEY到缓存服务器的Hash映射
189 |
190 | 具体算法过程: 先构造2^32的整数环(一致性Hash环), 根据节点名称的Hash值(其分部范围是[0, 2^32 - 1]), 将缓存服务器节点放置在这个Hash环上。
191 |
192 | 然后根据需要缓存数据的KEY值计算得到其Hash值(其范围也是[0, 2^32 - 1]), 然后在Hash环上顺时针查找距离这个Key的Hash值最近的缓存服务器节点
193 |
194 | 就完成了KEY到服务器的Hash映射查找
195 |
196 | 当服务器扩容时 只需要讲新节点插入一致性Hash环即可, 影响的只有整个环中的一小段
197 |
198 | 3台服务器扩容到4台服务器时 命中原先概率为75%
199 |
200 | 100台服务器扩容增加一台服务器 继续命中的概率为99%
201 |
202 | 具体应用中 这个长度为2^32的一致性Hash环通常使用二叉树查找实现, Hash查找的过程是在二叉查找树中找不少于查找树的最小数值。
203 |
204 | 当然这个二叉树最右边椰子节点和最左边的椰子节点相连接, 构成环
205 |
206 | 但是还有一个小问题
207 |
208 | 新加入的节点Node3只使Node1收益了, 即一部分原来要访问Node1的数据要访问Node3(概率上为50%)
209 |
210 | 但是原先的Node0和Node2不受影响, 意味着Node0和Node2缓存数据量和压力是Node1和Node3的两倍
211 |
212 | 如果四个机器的性能一样, 那么这种结果显然不是我们需要的
213 |
214 | 计算机领域有句话: `计算机的任何问题都可以通过增加一个虚拟层来解决`
215 |
216 | 做法是 将每台物理服务器虚拟为一组虚拟缓存服务器, 将虚拟服务器的Hash值放置在Hash环上, KEY在还上先
217 |
218 | 找到虚拟服务器节点,再得到物理服务器的信息
219 |
220 | 这样新加入服务器节点时, 是将一组虚拟节点加入环中, 如果虚拟节点的数组足够多,
221 |
222 | 这组虚拟节点蒋辉影响统一多数目的已经在环上存在的虚拟节点,这些已经存在的虚拟节点又对应不同的物理节点
223 |
224 | 这样最终新加一台缓存服务器, 将会较为均匀的影响原来集群中所有的服务器
225 |
226 | ## 6.4 数据存储服务器集群的伸缩性设计
227 |
228 | 和缓存服务器集群不同, 数据库存储服务器集群的伸缩性对数据的持久性和可用性提出了更高的要求
229 |
230 |
231 |
232 | ### 6.4.3 NoSQL数据库的伸缩性设计
233 |
234 | NoSQL: Not Only SQL,表示NoSQL只是关系数据库的补充,而不是替代方案
235 |
236 | # 随需应变: 网站的可拓展架构
237 |
238 |
239 |
240 |
241 |
--------------------------------------------------------------------------------
/dan_yuan_ce_shi_de_yi_zhu.md:
--------------------------------------------------------------------------------
1 | # 单元测试的艺术
2 |
3 | #0. 总结
4 |
5 | 1~2章介绍的是单元测试的基本概念
6 |
7 | 3~6在教你如何测试
8 |
9 | 7~8教你怎么写好代码
10 |
11 | 9: 鸡汤
12 |
13 | 10: 对付遗留代码
14 |
15 | 11: 好好设计代码吧
16 |
17 | #1. 入门
18 |
19 | 优秀单元测试的特性
20 |
21 | 1. 自动化,可重复执行
22 | 2. 很容易实现
23 | 3. 以后还有意义
24 | 4. 任何人都能一键运行
25 | 5. 速度很快
26 | 6. 独立于其他测试的运行
27 | 7. 如果它失败了,能快速定位问题
28 |
29 | 什么是集成测试
30 |
31 | 依赖到一个或多个真实依赖物,例如真实的系统时间,真实的文件系统,真实的数据库.
32 |
33 | 单元测试和集成测试的区别
34 |
35 | 集成测试会使用真实依赖物,而单元测试则把被测试单元和其以来无隔离开.
36 |
37 | 单元测试要点
38 |
39 | 1. 测试的命名 测试的可维护性 测试的可读性
40 | 2. 该成果的时候成果,该失败的时候失败
41 |
42 | # 2 第一个单元测试
43 |
44 | 测试的命名
45 | 1. UnitOfWork_Scenario_ExpectedBehavior
46 | 2. UnitOfWork: 被测试的方法、一组方法或者一组类
47 | 3. Scenario: 测试进行的假设条件
48 | 4. ExpectedBehavior: 在测试场景指定的条件下,你对呗测试方法行为的预期
49 |
50 | 单元测试主要的三个行为
51 |
52 | 1. 准备(Arrange)对象,创建对象,进行必要的设置
53 | 2. 操作(Act)对象
54 | 3. 断言(Assert) 某件事情的预期
55 |
56 | # 3 使用存根破除依赖
57 |
58 | 存根跟模拟对象的区别是: 两者类似,但是我们需要对模拟对象进行断言,而不会对存根进行断言
59 |
60 | 这里主要是为了烂代码去写更多的代码去实现测试,感觉会本末倒置
61 |
62 | 使用IOC可优好的测试.
63 |
64 | 同意赞同重构代码,使其易于测试
65 |
66 | # 4 使用模拟对象进行交互测试
67 |
68 | ## 4.1 基于值测试,基于状态测试,和交互测试
69 |
70 | 伪对象、存根、模拟对象的区别
71 |
72 | 1. 伪对象指模拟对象/存根
73 | 2. 如果伪对象用于检测一个交互,这个伪对象为模拟对象,否则为存根
74 |
75 | ## 4.2 模拟对象和存根的区别
76 |
77 | 模拟对象和存根的根本区别: 存根永远不会导致测试失败,而模拟对象可以
78 |
79 | 这个作者也是醉了..
80 |
81 | 第三、四章说完就说这两有缺陷,,这抛砖引玉...好啊......擦..
82 |
83 | # 5 隔离(模拟)框架
84 |
85 | 麻鸡...
86 |
87 | #6 深入了解隔离框架
88 |
89 | ##6.2 优秀隔离框架的价值
90 |
91 | 提高测试健壮性的功能
92 |
93 | 1. 递归伪对象
94 | 2. 对行为和验证默认忽略参数
95 | 3. 非严格验证和行为
96 | 4. 大范围伪造
97 |
98 | # 7. 测试层次和组织
99 |
100 | # 7.4将测试类映射到源代码
101 |
102 | 1. 集成测试和单元测试必须分块
103 | 2. 将每个待测试类对应一个测试类
104 | 3. 当某个方法需要特别多的测试,新建对应的一个测试类
105 |
106 | ## 7.6 为应用程序构建测试API
107 |
108 | ### 7.6.3 把你的API介绍给开发人员
109 |
110 | 1. 偶尔结对编程,一带一
111 | 2. 准备小文档/速查表
112 | 3. 在团队会议上讨论API变更
113 | 4. 新人入职带过文档
114 | 5. 进行测试审查
115 |
116 | #8 优秀单元测试的支柱
117 |
118 | 优秀测试
119 |
120 | 1. 可靠
121 | 2. 可维护
122 | 3. 可读
123 |
124 | ## 8.1编写可靠测试
125 |
126 | ### 8.1.2避免测试中的逻辑
127 |
128 | 单元测试不应该有任何 switch if else for等语句
129 |
130 | 如果第一个断言失败了,你还会关心下一个断言的结果吗?如果会,就把它分为两个单元测试
131 |
132 | ## 8.2 编写可维护的测试
133 |
134 | ### 8.2.4 实施测试隔离
135 |
136 | 测试中的臭味道
137 |
138 | 1. 强制的测试顺序
139 | 2. 隐藏的测试调用
140 | 3. 共享状态损坏: 测试共享内存里的状态,却没有状态回滚
141 | 4. 外部共享状态损坏: 集成测试共享资源,却没有回滚资源
142 |
143 | # 9 在组织中引入单元测试
144 |
145 | 这里一看就是一碗鸡汤,就看你干不干
146 |
147 | ## 9.1 变成倡导者
148 |
149 | ### 9.1.1 准备面对质疑
150 |
151 | 回答自己最难的问题
152 |
153 | ### 9.1.2 找到支持者和反对者
154 |
155 | 支持者: 教他们回答问题
156 |
157 | 反对者: 请他们参与其中的一些细节,切记不要告诉他们,他们哪里做得不好
158 |
159 | ### 9.1.3 找到可能的切入点
160 |
161 | 1. 选择较少团队
162 | 2. 经验少的一般愿意接受变革,经验多且墨守成规的,你很难改变他们,所以找一个技术经理愿意变革,且团队成员经验较浅的团队
163 | 3. 经常性代码审查,要面对面的审查
164 | 4. 自下而上
165 |
166 |
167 | ##9.2 成功之道
168 |
169 | ### 9.2.4 使进度可见
170 |
171 | ### 9.2.5 设置具体目标
172 |
173 | ## 9.3 失败原因
174 |
175 | ### 9.3.3 不好的实现和第一印象
176 |
177 | 你自己要把整体的布局想好了,才开始实施,自己必须要牛逼,不然自己也不咋懂,就开始瞎弄,可能会丢掉以后的机会
178 |
179 | ### 9.3.4 缺少团队的支持
180 |
181 | 你应该逐个交谈,并回答他们的尖锐问题
182 |
183 | 这章主要讲心理学和人际交往学
184 |
185 | 主要考虑一下6个影响因素
186 |
187 | 1. 个人能力: 你真正掌握这门技术吗
188 | 2. 个人动机: 这个人把事情做对了吗,遇到困难能坚持吗
189 | 3. 社会能力: 你是否给这个人提供帮组,在关键时刻
190 | 4. 社会动机: 这个人周围的人是否鼓励正确的行为,反对你的人能否体现出其正确的行为
191 | 5. 组织能力: 是否存在坏境因素,使其方便的提供帮助
192 | 6. 组织动机: 如果你做了正确/错误的事情,能得到预期的回报吗
193 |
194 | ## 9.5 质疑和回答
195 |
196 | ### 9.5.6 我们有大量没有测试的代码: 应该从哪里开始
197 |
198 | 20%的代码包含80%的bug,从这里开始吧
199 |
200 | # 10. 遗留代码
201 |
202 | ## 10.3 在重构前编写集成测试
203 |
204 | 有些代码无法单元测试
205 |
206 | 1. 进行集成测试
207 | 2. 重构
208 | 3. 逐一单元测试
209 |
210 | ##10.5 总结
211 |
212 | 要了解各个组件的依赖书和逻辑量,初学者可以先对最简单的进行测试
213 |
214 | # 11.设计与可测试性
215 |
216 | 好的代码是可以测试的
--------------------------------------------------------------------------------
/dombian_cheng.md:
--------------------------------------------------------------------------------
1 | # DOM编程
2 |
3 | 浏览器独自实现JS和DOM
4 |
5 | IE中.分别存在`jscript.dll` & `mshtml.dll`
6 |
7 | 为什么DOM会慢
8 |
9 | 因为分开实现,之间通过接口访问.之间需要`过桥费`
10 |
11 | ##1. 优化建议
12 |
13 | 1. 谨慎使用循环操作DOM
14 |
15 | 因为这个过桥费,所以谨慎使用循环.
16 |
17 | 若DOM操作有顺序,先放在一个字符串里,汇总完后再一次修改DOM.
18 |
19 | 2. `innerHTML` & `createElement`
20 |
21 | 在旧浏览器中`innerHTML`比`标准DOM操作(document.createElement())`快
22 |
23 | 现代浏览器相差无几,甚至有点反超.
24 |
25 | 3. 节点`clone`
26 |
27 | 先`createElement`好所需元素.
28 |
29 | 在循环中`clone`
30 | 4. HTML集合优化
31 |
32 | 1. document.getElementByName();
33 | 2. document.getElementsByClassName();
34 | 3. document.getElementsByTagName();
35 | 4. document.images;
36 | 5. document.links;
37 | 6. document.forms;
38 | 7. document.forms[0].elements
39 |
40 | 以上方法军返回HTML集合对象,非数组,因为没有`push()`和`slice()`等方法,可以根据索引获取对象和length获取长度
41 |
42 | 建议如果频繁操作HTML集合,可转换为数组.
43 |
44 | 避免在for循环中使用HTML集合.length因为每次都会重新计算.
45 |
46 | 尽量采用局部变量,但要用到对象成员时.
47 | ```javascript
48 | function K(){
49 | var coll document.getElementsByTagName('div'),
50 | len = coll.length,
51 | name ='',
52 | el =null;
53 | for(var count =0;count