毛姆三部曲

手机上断断续续看完了毛姆的《刀锋》。这样算下来,竟然看过了毛姆的三部长篇小说。除了这本,还有《月亮与六便士》和《人生的枷锁》。

最开始看的《月亮与六便士》。当时可能是因为“满地都是六便士,他却抬头看见了月亮”这句话。事业有成的主人公查尔斯放弃所有,抛妻弃子,去追寻自己的绘画梦想。背信弃义,违背社会常理,一心追求艺术。很多人喜欢本书,可能是主人公做了很多现实中人们想做而没有勇气做的事情吧,尽管他为了自己追求的艺术做了很多“龌龊”的事情。

但是毕竟我们普通人不像查尔斯那样有艺术天分,甚至于很多人都不知道要去追求什么,或者不懂人生的意义,什么才是有意义的生活。

而《刀锋》的主人公,拉里,在一战经历了战友在自己面前中弹牺牲后,对人生的意义产生了疑惑,迷茫。于是他战后回国,不上学,不工作,不结婚,周游各地,去追寻人生的终极意义。在印度大彻大悟后,返回美国做一名普通的卡车司机。也许,对于顿悟后的他来说,做什么都不重要,因为人生本来可能就毫无意义,或者,无论做什么都有意义。

《人生的枷锁》则更加现实。主人公菲利普自幼身残,父母早亡,从孤儿到上学,工作的经历,到处都充满了荆棘。在重重枷锁中,菲利普难寻自由,最终发现自己经历的一切就是人生的本来面目。而所有的一切欢笑与泪水,都构成了人生的意义,而追求人生的意义,是没意义的。

这三本书,都在讲人生的意义,如何过自己的一生,但是又各有不同侧重。最开始看的《月亮与六便士》,但是最喜欢的还是《人生的枷锁》,毕竟,我们都是普通人,也没什么艺术追求,都在过着枷锁的人生。但是,如果你迷茫,你困惑,我推荐看《刀锋》。

关于说教

毛姆被称为故事圣手,最会讲故事的人。你可以在书中看到很多道理,摘抄名言警句的话,基本上要随处可见。但是作者不是简单的说教,他会先讲个故事,故事里有各色各样的人,每个人都能找到自己的影子,然后借故事里的人物对话和行为后果来点出他想说的道理。

可能自己是理科生,因此,平时喜欢讲道理。Q老是说我喜欢讲大道理。但是讲道理,很多人听不进去,即使听了也未必会去做。或许,我们应该学学毛姆,讲个故事,不讲大道理,让听者自己去领悟,那么效果可能会更好一点。

于是,我想到了孩子教育。如果平时跟孩子沟通时,或者想教训孩子的时候,换成讲故事的方式,可能会事半功倍。毕竟,哪个孩子不喜欢听故事呢。

生活的意义

摘自《月亮与六便士》:

做自己最想做的事,
生活在自己喜欢的环境里,
淡泊宁静,与世无争,
这难道是糟蹋自己吗?
与此相反,
做一个著名的外科医生,
年薪一万镑,
娶一位美丽的妻子,
就是成功吗?
我想,
这一切都取决于一个人如何看待生活的意义,
取决于他认为对社会应尽什么义务,
对自己有什么要求。

关于生活

摘自王小波的《黄金时代》:

那一天我二十一岁,
在我一生的黄金时代。
我有好多奢望。
我想爱,想吃,
还想在一瞬间变成天上半明半暗的云。
后来我才知道,
生活就是个缓慢受锤的过程,
人一天天老下去,
奢望也一天天消失,
最后变得像挨了锤的牛一样。
可是我过二十一岁生日时没有预见到这一点。
我觉得自己会永远生猛下去,
什么也锤不了我。

安装插件

执行菜单【Tools】-【Command Palette】,或者CMD+SHIFT+P,打开命令面板,输入关键词“install package”,下拉选择【Package Control: Install Package】,然后输入要搜索的插件名称,模糊匹配查询后,下拉选择要安装的插件即可安装。

可以通过CTRL+`组合键来打开控制台查看命令的执行日志。

如果执行时报错误,比如出现

“Package Control: Error downloading package. HTTP exception InvalidCertificateException”。

可以尝试在【Preferences > Package Settings > Package Control > Settings - User】打开配置文件后,在其中添加:

"downloader_precedence":
{
"osx":
[
"curl"
]
},

这个配置的含义在【Preferences > Package Settings > Package Control > Settings - Default 】配置文件中有注释,用来控制下载使用的库。

// The downloader backends that should be used for HTTP(S) requests, split
// by operating system to allow for configuration to be shared.
//
// Valid options include: "urllib", "curl", "wget", (Windows-only) "wininet"
//
// This setting allows Windows users to bypass wininet and use urllib
// instead if they machine or network presents trouble to wininet. Some
// OS X and Linux users have also reported better luck with certain proxies
// using curl or wget instead of urllib.
//
// The "curl" and "wget" options require the command line "curl" or "wget"
// program installed and present in the PATH.
"downloader_precedence": {
"windows": ["wininet"],
"osx": ["urllib"],
"linux": ["urllib", "curl", "wget"]
},

打开自动换行

执行菜单【Tools】-【Command Palette】,或者CMD+SHIFT+P,打开命令面板,输入关键词“word wrap”, 下拉选择【Word Wrap: Toggle】,可以打开/关闭自动换行

或者执行【View】-【Word Wrap】。

显示打开文件的字符编码格式

安装插件“ShowEncoding”。安装完成后,在编辑器的左下角默认会展示当前打开文档的编码格式。

格式化JSON

安装插件“Pretty JSON”。安装完成后,在命令面板(CMD+SHIFT+P),输入“Pretty JSON”即可以选择相关的命令来格式化或者压缩json格式。

2020年已经过去一个月了,今晚统计分析了去年的读书情况,做一下回顾与总结。数据截止到2020年1月31日。

阅读量

去年一年总共看完了43本,这个数量应该算是比以前的任何一年都要高。简单分析了下原因,主要还是由于去年一年基本都在出差。出差虽然很忙,但是却多出来了两块时间,一块是每周来回出差地的火车上的时间,另外一块是每天地铁的时间,之前不出差的时候每天开车上下班。当然,时间有了,另外一个原因是,今年开始使用手机上阅读类APP(Kindle和微信读书),而微信读书又时不时送个无限卡。天时地利人和,所以,今年阅读数也创出了历史新高。

阅读终端分布

用Excel分析了下今年阅读终端分析如下图,可以看到微信读书大约占了一半的比例。实体书的占比不到三分之一了。当然家里还是有不少买了没来得及看的纸质书,也是新的一年要重点消灭掉的。手机看书确实增加了看书的便利性,并且还避免了搬家时的痛苦。
20200131-reading-source.png

作者国籍分布

20200131-reading-region.png

美中日三国占了大部分。

图书分类分布

20200131-reading-category.png

整体来说,去年看的书类型比较杂,专业书看的偏少。去年曾经进行过关于日本的专题阅读,不过大部分还是挑热门的看。

读书列表与评分

20200131-reading-list.png

以上是去年的读书列表,后面的评分是个人的主观评价。里面评分比较高的,主要包含两个系列,三体(1-3),和那不勒斯四部曲。豆瓣上打了五星。另外,重温了经典《围城》。

  • 《现代日本史 : 从德川时代到21世纪》: 这本讲日本历史的大部头,开启了对历史的兴趣,今年可能会多看一些历史方面的书,历史总在不停的重复,读史以知今。
  • 《股票大作手回忆录》:跟着趋势去操作,只在上涨时买进下跌时卖出,很多投机的原则与底线值得思考。值得再读的书。
  • 《非暴力沟通》:观察,感受,需求,请求。四部曲。对自己,通过”我观察到……,我感觉……,是因为我需要……,我请求…”来表达自己。对别人,通过“你观察到……,你感觉……,是因为你需要……,所以你想要……”来倾听他人,理解他人。好书值得实践。

2020的读书目标&立FLAG

  • 把家里买了没读的纸质书读完
  • 专题阅读-历史方向
  • 不追求数量,精读,读经典,有输出
  • 减少虚构类的,增加非虚构类的

字符串类型字段末尾有空格匹配问题

现象:如果字段的值末尾有空格,那么在根据这个字段去查询时,会出现“不精确”的匹配,去掉了末尾的空格。

查了下MySQL的文档,原来是取决于MySQL的collation规则,当然也和MySQL的版本相关。

针对MySQL 5.7以及之前的版本(https://dev.mysql.com/doc/refman/5.7/en/char.html),是这样的:

All MySQL collations are of type PAD SPACE. This means that all CHAR, VARCHAR, and TEXT values are compared without regard to any trailing spaces. “Comparison” in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant. This is true for all MySQL versions, and is not affected by the server SQL mode.

也就是说,在5.7版本以及之前的版本,在做查询比较时,CHAR,VARCHAR,TEXT类型的字段,会把末尾的空格去掉再比较,并且无法改变这个规则。如果一定要精确的匹配,可以使用“LIKE”而非“=”。

而针对MySQL 8以及以后版本(https://dev.mysql.com/doc/refman/8.0/en/char.html),则是这样的:

Most MySQL collations have a pad attribute of PAD SPACE. The exceptions are Unicode collations based on UCA 9.0.0 and higher, which have a pad attribute of NO PAD. To determine the pad attribute for a collation, use the INFORMATION_SCHEMA.COLLATIONS table, which has a PAD_ATTRIBUTE column.

在MySQL 8之后,部分collation可以支持选择NO PAD,也就是说可以选择不忽略末尾的空格再比较。

在MySQL的系统表(INFORMATION_SCHEMA.COLLATIONS)中,可以查询PAD_ATTRIBUTE列的值,来查看不同的collation对应的规则。

比如在MySQL 8的版本(5.7以及以下不存在PAD_ATTRIBUTE列,执行会报找不到列)中执行如下SQL:

SELECT COLLATION_NAME, PAD_ATTRIBUTE FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME LIKE 'utf8mb4_bin';

会显示两个结果:

+---------------------+---------------------+
| COLLATION_NAME   | PAD_ATTRIBUTE |
+---------------------+---------------------+
| utf8mb4_bin      | PAD SPACE |
+---------------------+---------------------+
| utf8mb4_0900_bin | NO PAD |
+---------------------+---------------------+

所以,可以通过修改字符集的COLLATION来实现对末尾空格处理逻辑。当然,采用LIKE匹配也可以实现精确匹配的效果。

由于处理末尾的规则不一样,所以当使用PAD SPACE规则时,如果该列有唯一性约束,那么通过末尾增加空格来区分两个值也是行不通的。

For those cases where trailing pad characters are stripped or comparisons ignore them, if a column has an index that requires unique values, inserting into the column values that differ only in number of trailing pad characters will result in a duplicate-key error. For example, if a table contains 'a', an attempt to store 'a ' causes a duplicate-key error.

大小写匹配问题

这个其实也是跟库表的COLLATION相关的。按照COLLATION的命名规则(https://dev.mysql.com/doc/refman/5.7/en/charset-collation-names.html), 带有ci后缀的那些COLLATION是忽略大小写的(Case Insensitive)。

可以通过执行

SELECT * FROM INFORMATION_SCHEMA.COLLATIONS

查看字符集与其对应的COLLATON列表。

找了许久竟然发现没有现成的生成多模块Maven项目的方法,难怪好多人要写脚手架了。全新搭建一个新的工程还是有一些工作量的,这里先把创建多模块的Maven项目的方法记录下。

什么是多模块的Maven项目

什么是多模块的Maven项目就不细说了。一句话,多模块的Maven项目有一个特点是,位于项目根目录的主POM文件的packaging类型是pom,并且包含多个module。POM文件类似如下:

<project>
    ......
    <packaging>pom</packaging>
    ......
    <modules>
        <module>module1</module>
        <module>module2</module>
    </modules>
</project>

项目下的每一个模块都是普通的Maven项目,并且可以独立打包,当然也可以通过主POM打包。

多模块的Maven项目有什么好处

降低重复,多个子模块重用依赖与配置,并且可以实现一键打包多个子模块的操作。

如何创建多模块的Maven项目

我们将创建一个包含两个子模块的Maven项目,假设groupId=com.test,主子工程的artifactId分别为test-project,test-project-service,
test-project-web。使用时你可以改成你自己的名称。

首先生成主项目,在命令行执行如下命令:

mvn archetype:generate \
-DarchetypeGroupId=org.codehaus.mojo.archetypes \
-DarchetypeArtifactId=pom-root \
-DarchetypeVersion=RELEASE \
-DgroupId=com.test \
-DartifactId=test-project  \
-Dversion=0.0.1-SNAPSHOT \
-DinteractiveMode=false 

然后切换到生成的根目录下,在这个例子中是test-project目录。

接下来生成两个子模块,依次执行如下命令:

mvn archetype:generate \
-DgroupId=com.test \
-DartifactId=test-project-service  \
-Dversion=0.0.1-SNAPSHOT \
-DinteractiveMode=false 

mvn archetype:generate \
-DgroupId=com.test \
-DartifactId=test-project-web  \
-Dversion=0.0.1-SNAPSHOT \
-DinteractiveMode=false

这两个命令会在根目录下生成2个子工程,并且在子工程的POM文件中指定了主项目作为他们的parent。同时也在主POM中添加这些子项目到modules元素下。

这样就完成了包含两个模块的Maven项目了,打开IDE,导入Maven工程即可。