Many Links 0705

1.
首先推荐来自今天的 湾区日报
从最初坚持每天5篇分享至今已经1205期了,点赞作者.
1)最好的商业模式, 微软、苹果、Netflix:花钱的用户是用产品的人;谷歌与FB:花钱的是广告商,用产品的人免费;Amazon、腾讯、阿里:小比例的超级用户花大钱,间接让整个生态变得更好。哪种商业模式好?
2)Firefox + Pocket:打造更好的文章推荐引擎。恐怕很多人不知道Pocket已经被Mozilla收购了。如果你有使用Firefox,打开一个空白新窗口就会看到Pocket推荐的文章,这是根据你使用Firefox的本地浏览记录推荐的。
2.
Microsoft: The Early Days: http://www.memecentral.com/mylife.htm
这篇也是湾日的推荐。
1981年,作者和其老板Charles Simonyi从计算机人机交互界面发展先驱的施乐走出,经同事即3Com创始人的建议,一起成为微软第77位员工,当时微软刚要开始做应用程序,开始山寨Mac上的电子表格,后来开始做“长得像电子表格的字处理系统”,也就是Word。
Word,成为了之后数年的Revenue Bomb, 难怪当年求伯君把自己关在张旋龙(金山创始人,张小龙的哥哥,不是八卦里的微信张小龙)为他在深圳包的一个房间里,日夜兼程写出了字处理系统WPS, 不过当初目标据说是为了超越当时尚火WordStar,WordStar兼容DOS,不过90年后被MS Word超越。
求伯君后来吐露,虽然WPS每年收入数千万(1993年前后),但是自己只是个给老板打工的。

3.
接 2.
文中提到的Charles Simonyi,中文译作 查尔斯·西蒙尼,微软 Word/Excel 开发的Leader,安迪·格鲁夫的老乡,曾经微软首席架构师,高智囊团的核心,所见即所得(What you see is What you get)的发明人。
不仅上述实际产出,图形用户界面等,查尔斯·西蒙尼还给微软带去了:
1)开发应用软件的经验,当时MS不具备的系统层之上的软件应用经验。
2)关于程序员生产力的理论,被Gates称为“软件工厂”理论,也是数年后逃离微软的人吐槽的金字塔层级理论。
我曾在学校图书馆角落里看过一本介绍VB之父Alan Cooper的书,里面提到了西蒙尼非比寻常的兴趣:
事实上,历史上前6位太空游客,两位就是曾从事程序员的职业,其他四位或是电子计算机相关专业或是创建计算机相关的公司/投资。最让国内程序员熟悉的可能就是一位生于南非的IT界的企业家,马克·沙特尔沃思,Canonical公司创立者,Canonical就是组织创造了Ubuntu的公司,所以到了第二年10月份,知道Ubuntu组织免费提供 Ubuntu系统光盘,那个使用google还可以畅行无阻的时代,我就申请了一个32位的系统盘,珍藏着。
4.
the hidden costs of touchscreens
https://medium.com/@caseorganic/why-do-we-keep-building-cars-with-touchscreens-alt-the-hidden-lives-of-touchscreens-55faf92799bf
触摸屏真的方便了人们的操作了吗?不是所有场景都提高效率的,有的收银台的POS机变成平板电脑,收银员效率下降不少,得眼睛看屏幕才能操作。
我似乎理解了为什么这么多年过去了,国内许多大商场依旧是没有触摸屏的收银台,但更可能的原因是IBM的小型机及其系统确实太昂贵了。
其实,我确实更喜欢现在国内一些新型零售的触摸自助结账系统,不用排队,更免去了被花式插队带来的愤怒。
但这么做,似乎也淘汰了一批收银员,而这些人中,许多可能是出来打点工,给家庭减少财务负担的,还未到退休年纪或刚到大城市尚未着落的女性。
5.
The Story Behind How Pocket Hit 20M Users with 20 People
http://firstround.com/review/the-story-behind-how-pocket-hit-20m-users-with-20-people
创立八年,而前四年都是一个人在单打独斗
记得13年就在使用pocket,不过那时确实困惑了“read it later”和packet是哪个好久?完全没想到居然是一个人在运营
6.
大概上个月爆出的 新版JDK += 操作符的副作用
很详细的:JDK 9/10/11: Side Effects from += on Java String
http://marxsoftware.blogspot.com/2018/06/JDK-8204322.html
https://stackoverflow.com/questions/50683786/why-does-arrayidx-a-increase-idx-once-in-java-8-but-twice-in-java-9-and-1
https://bugs.openjdk.java.net/browse/JDK-8204322
http://mail.openjdk.java.net/pipermail/compiler-dev/2018-June/011997.html
7.
是否遇到过 “javax.net.ssl.SSLException: Received fatal alert: protocol_version”的异常?
实际上这是JDK1.7默认支持的TLS版本导致的异常,JDK1.7+ 默认支持的TLS版本不是TLSv1.2
https://scnuwang.github.io/2017/10/11/JDK1.7%E9%BB%98%E8%AE%A4%E6%94%AF%E6%8C%81%E7%9A%84TLS%E7%89%88%E6%9C%AC%E5%AF%BC%E8%87%B4%E5%BC%82%E5%B8%B8/
查看JDK1.7+ 支持的协议
http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext
解决方案:在发送请求前设置系统属性:System.setProperty(“https.protocols”, “TLSv1.2”);
https://stackoverflow.com/questions/9749339/does-tomcat-support-tls-v1-2
8.
http://jaminzhang.github.io/os/Linux-IO-Monitoring-and-Deep-Analysis/
Linux IO 监控与深入分析
作者总结的很详细,才知道原来原生的还有这么多命令可用,这些命令还可以这么用。

1) 系统级 IO 监控: iostat -xdm 1
如果 %iowait 的值过高,表示磁盘存在 I/O 瓶颈。
如果 %util 接近 100%,说明产生的 I/O 请求太多,I/O 系统已经满负荷,该磁盘可能存在瓶颈。
如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;
如果 await 远大于 svctm,说明 I/O 队列太长,I/O 响应太慢,则需要进行必要优化。
如果 avgqu-sz 比较大,也表示有大量 IO 在等待。
2) 进程级 IO 监控 iotop 和 pidstat
pidstat -d 1
pidstat -u -r -d -t 1
可以回答系统级 IO 监控不能回答的 2 个问题
距离业务层相对较近(例如,可以统计进程的读写量)
但是也没有办法跟业务层的 read, write 联系在一起,同时颗粒度较粗,没有办法告诉你,当前进程读写了哪些文件?耗时?大小?
3) 业务级 IO 监控 ioprofile
ioprofile 命令本质上是 lsof + strace ioprofile 可以回答你以下三个问题:
当前进程某时间内,在业务层面读写了哪些文件(read, write)?
读写次数是多少?(read, write 的调用次数)
读写数据量多少?(read, write 的 byte 数)
注: ioprofile 仅支持多线程程序,对单线程程序不支持. 对于单线程程序的 IO 业务级分析,strace 足以。
总结: ioprofile 本质上是 strace,因此可以看到 read,write 的调用轨迹,可以做业务层的 IO 分析(mmap 方式无能为力)
4) 文件级 IO 监控
文件级 IO 监控可以配合/补充”业务级和进程级” IO 分析
文件级 IO 分析,主要针对单个文件,回答当前哪些进程正在对某个文件进行读写操作
lsof 或者 ls /proc/pid/fd
inodewatch.stp
lsof 告诉你当前文件由哪些进程打开


9.
jdk11比10包含哪些特性?
https://www.oschina.net/news/97145/jdk-11-jep-332?from=20180617
列出了相关JEP,可以点击原文查看,原文含详细链接

JDK 11 已确定了 15 个 JEP,下面是完整的列表:
181: 基于嵌套的访问控制(Nest-Based Access Control)
309: 动态类文件常量(Dynamic Class-File Constants)
315: 改进 Aarch64 Intrinsics(Improve Aarch64 Intrinsics)
318: Epsilon — 一个无操作的垃圾收集器(Epsilon: A No-Op Garbage Collector)
320: 删除 Java EE 和 CORBA 模块(Remove the Java EE and CORBA Modules)
321: HTTP Client (Standard)
323: 用于 Lambda 参数的局部变量语法(Local-Variable Syntax for Lambda Parameters)
324: Curve25519 和 Curve448 算法的密钥协议(Key Agreement with Curve25519 and Curve448)
327: Unicode 10
328: Flight Recorder
329: ChaCha20 和 Poly1305 加密算法(ChaCha20 and Poly1305 Cryptographic Algorithms)
330: 启动单一文件的源代码程序(Launch Single-File Source-Code Programs)
331: Low-Overhead Heap Profiling
333: 处于试验阶段的可伸缩低延迟垃圾收集器 ZGC: A Scalable Low-Latency Garbage Collector (Experimental)
336: 弃用 Pack200 工具和 API(Deprecate the Pack200 Tools and API)


10.
Kafka 源码解析之 Consumer 如何加入一个 Group(六)
http://matt33.com/2017/10/22/consumer-join-group/
推荐看作者总结的 Kafka 源码解析 系列
11.
数据库事务隔离标准分析
https://zhuanlan.zhihu.com/p/38214642
一直记不住的数据库隔离级别:

本文首先介绍了ANSI基于“异象”的隔离级别标准,并分析了其狭义和广义的描述;然后介绍了基于锁的隔离级别标准,与ANSI隔离级别进行了比较;最后分析快照隔离级别,在ANSI隔离级别标准基础上,提出了两种新的“异象”,得出快照隔离在几种标准隔离级别特性中的位置。
ANSI SQL-92标准(http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt)将数据库并发事务间的隔离性行为划分为3种"异象(phenomena)",从低到高的自然语言定义依次为:
P1 脏读 (“Dirty read”): SQL-transaction T1 modifies a row. SQL- transaction T2 then reads that row before T1 performs a COMMIT. If T1 then performs a ROLLBACK, T2 will have read a row that was never committed and that may thus be considered to have never existed.
P2 不可重复读 (“Non-repeatable read”): SQL-transaction T1 reads a row. SQL- transaction T2 then modifies or deletes that row and performs a COMMIT. If T1 then attempts to reread the row, it may receive the modified value or discover that the row has been deleted.
P3 幻读 (“Phantom”): SQL-transaction T1 reads the set of rows N that satisfy some . SQL-transaction T2 then executes SQL-statements that generate one or more rows that satisfy the used by SQL-transaction T1. If SQL-transaction T1 then repeats the initial read with the same , it obtains a different collection of rows.
P1/P2/P3的形式化描述
根据标准文档的定义,可以将这三种异象使用形式化语言描述如下,称为A1/A2/A3(其中w1[x]表示事务1写入记录x,r1表示事务1读取记录x,c1表示事务1提交,a1表示事务1回滚,r1[P]表示事务1按照谓词P的条件读取若干条记录,w1[y in P]表示事务1写入记录y满足谓词P的条件):

A1 脏读:w1[x] … r2[x] … (a1 and c2 in any order)
A2 不可重复读:r1[x] … w2[x] … c2 … r1[x] … c1
A3 幻读:r1[P] … w2[y in P] … c2 … r1[P] … c1
上述A1/A2/A3形式化描述,根据标准定义的P1/P2/P3异象的自然语言描述转化而来,但是ANSI标准定义的异象只针对了单个记录或谓词描述,对于多条记录需满足业务一致性的场景并未能覆盖(比如两个账户间转账要求余额总和不变),举例如下:
H1:r1[x=50]w1[x=10] r2[x=10]r2[y=50] c2 r1[y=50]w1[y=90] c1
事务1执行账户x向账户y转账40,事务2读取到了进行到了一半的事务1(Read Uncommitted),破坏了余额总和的一致性
因为事务1并未回滚,H1的行为并不符合A1的形式化定义
H2:r1[x=50] r2[x=50]w2[x=10]r2[y=50]w2[y=90] c2 r1[y=90] c1
事务2执行账户x向账户y转账40,事务1在事务2提交前后读取到了破坏余额总和一致性的数据(Unrepeatable Read)
因为事务1并未重复读取记录x,H2的行为并不符合A2的形式化定义
H3:r1[P] w2[insert y to P] r2[z] w2[z] c2 r1[z] c1
事务2增加新雇员并更新雇员总数z,事务1在事务2提交前后读取到了破坏雇员列表与雇员总数的一致性的数据(Phantom)
因为事务1并未重复读取谓词P指定的数据集合,H3的行为并不符合A3的形式化定义.
因为要增强对上述H1/H2/H3异象的约束,论文将A1/A2/A3的形式化描述称为“狭义的描述(strict interpretations)”,然后增加了“广义的描述(broad interpretation)”,去除了strict interpretations中对事务提交、回滚和数据读取范围的约束,只保留事务之间读写的时序关系,即事务之间只要包含如下时序的操作,即可能产生包含H1/H2/H3在内的异象,如下:
P1 脏读:w1[x] … r2[x] … ((c1 or a1) and (c2 or a2) in any order)
P2 不可重复读:r1[x] … w2[x] … ((c1 or a1) and (c2 or a2) in any order)
P3 幻读:r1[P] … w2[y in P] … ((c1 or a1) and (c2 or a2) in any order)
在上述形式化描述下,禁止P1即可禁止H1,禁止P1/P2即可禁止H2,禁止P1/P2/P3即可禁止H3。至此,ANSI标准隔离级别定义的三种异象,可以被扩展为适用范围更广的的P1/P2/P3的形式化定义,这种隔离级别定义被论文称之为“phenomena-based”,即基于“异象”的隔离级别定义。


可以惨考这篇文章,实例分析,加深印象
《A Critique of ANSI SQL Isolation Levels》论文实验
https://zhuanlan.zhihu.com/p/38334464
12.
国内Elasticsearch早期布道者 Medcl 的新书计划:Elastic 搜索开发实战
https://elastic-search-in-action.medcl.com/0.1_abstract.html
13.
很不错的功能: Kafka 1.1新功能:数据的路径间迁移
http://www.cnblogs.com/huxi2b/p/9214592.html
14.
JDK 11中将会加入令人惊叹的ZGC(不到2毫秒)
http://openjdk.java.net/jeps/333
https://zhuanlan.zhihu.com/p/38348775?group_id=993277353635659776
15.
http://vmlens.com/articles/3_tips_volatile_fields/
艺海拾贝:3 Tips for volatile fields in java

Volatile fields are one of built-in mechanism to write multi-threaded java.
Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread. … The visibility effects of volatile variables extend beyond the value of the volatile variable itself. When thread A writes to a volatile variable and subsequently thread B reads that same variable, the values of all variables that were visible to A prior to writing to the variable become visible to B after reading the volatile variable.
— Java Concurrency in Practice - Brian Goetz, et al.
1) Use volatile fields when writes do not depend on its current value.
2) Use volatile fields for reading and locks for writing
3) Use with JDK 9 VarHandle for atomic operations.


16.
来点轻松的:
计算机领域有哪些经典的典故或笑话?
https://www.zhihu.com/question/20034686
看到一个有趣的链接:
RegEx match open tags except XHTML self-contained tags
https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags
第一个高赞答案分析了一堆理由,然后作者大概是 苦正则表达式匹配 html久已,还故意留了一段 血腥字体 的示例
可怜的 stackoverflow 编辑 或许是苦于“Please do not flag it for our attention”特意加了一段 网页显示没问题,原文就是这样 的声明。
开头还加了一段 lock 讨论的声明,太多讨论无关主题
向 stackoverflow 对技术对社区质量负责任的态度致敬。