Java 11 在 2018 年 9 月 25 日发布。这是 Java 8 之后首个长期版本。
因为我本地使用 asdf 来管理 Java 的多个版本,所以直接使用 asdf 来安装:
asdf install java adoptopenjdk-11.0.17+8
asdf global java adoptopenjdk-11.0.17+8
java -version
Http Client 几乎被重写,支持异步非阻塞。
包名从 jdk.incubator.http
改为 java.net.http
,通过 CompleteableFutures
提供非阻塞请求。新的 HTTP Client 提供了对 HTTP/2 的支持,兼容 HTTP/1.1 ,与主流的开源库(Apache HttpClient,Jetty, OkHttp)性能相差无几。
Java 在 Reactive-Stream 的实践,广泛使用了 Java Flow API。
模拟 GET 请求:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://openjdk.java.net/"))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
Epsilon 目标是开发一个内存控制器,不执行任何垃圾回收,提供完全消极的 GC 实现,最大限度降低内存占用和内存吞吐延迟时间。
通过 JVM 参数 -XX:+UseEpsilonGC
来开启。
一些特殊的场景可以不开启垃圾回收以方便进行比如性能测试,内存压力测试等等。
Java 11 可以直接运行一个单一的源码文件,Java 解释器可以直接在内存中编译,然后执行。所有的类都必须定义在同一个 Java 文件中。
这个功能特别适合想要简单了解一下 Java,写一些脚本文件的时候非常有用。
Java 10 开始就引入了 var 关键字,允许局部变量推断。
但在 Java 10 中有几个限制:
Java 11 中允许开发者直接在 Lambda 表达式中使用 var 进行参数声明。
Java 11 中提供了一种低开销的 Java 堆分配采样方法,能够得到堆分配的 Java 对象信息,并能够通过 JVMTI 访问堆信息。
ZGC 是 Z Garbage Collector ,GC 停顿时间短,不超过 10ms,能处理 T 级别堆大小。
实验阶段,只在 Linux/x64 上可用,在编译时加入参数才可以启用,并且使用时需要增加 JVM 参数。
低开销的事件信息收集框架。
启用参数:
-XX:StartFlightRecording
Backlog 是一个在日本非常流行的项目管理工具,用于追踪项目进度,查看甘特图,查看进度消费图。
Backlog 的英文原意指的是积压的工作,一系列的任务,或者待完成的事情。这个词通常被用在项目管理,软件开发中。
Backlog 上有一系列的术语
每一个任务都有四种状态:
这个任务状态也可以通过后台的设置进行自定义。
《天朝的崩溃:鸦片战争再研究》 是茅海建教授对于鸦片战争研究的集大成之作,是系统研究鸦片战争十余年所得的成果。在阅读之前,我本以为是一部非常学术的类似论文一样的著作,然而我只阅读了一章就改变了我的观点,作者以人物为核心,将历史事件以人物为核心串联,并收集各方面的文献材料,去还原历史的本来面貌,去摆正对一个历史人物的是非判断。并且作者的笔法流畅通顺,非常易读。
这本书很早就在待看列表中,不断地有人在不同的场合曾经提到过,在豆瓣的时间线看到过,在 Twitter 上看到过有人推荐。鸦片战争几乎是中国人尽皆知的近代耻辱的开始,1840 年就像是一个烙印,相信很多人都记得。但唯独很多人不知道的是鸦片战争究竟是如何爆发的,又是如何一步步战败的。我们的教科书只是让我们对鸦片战争有了一个大概的印象,但每一个细节都缺失了。这也是让我对这一本副标题为「鸦片战争再研究」的书产生兴趣的一个原因。
[[茅海建]],我还是第一次读这位教授的书,同样看介绍,这一本《天朝的崩溃》也是茅海建教授的成名之作。茅海建是华东师范大学历史系教授、北京大学历史学系兼职教授,师从陈旭麓教授。
这是一本还原鸦片战争前后相关人物、相关事件的历史著作,作者以翔实的文献材料,理性中立的评价,使得鸦片战争中的道光帝、林则徐、琦善、奕山等等人物形象跃然纸上。每次读到中途放下,就像是看电视剧中途休息,意犹未尽。
这本是一本讲述近 200 年前清王朝和英国的战争前因后果的历史著作,却不时的让我回想起过去三年的新冠疫情,主「剿」和主「抚」和如今的清零和开放;道光皇帝的优柔寡断,坚信祖宗留下来的制度尽善尽美只是朝廷存在诸多腐败的问题和如今左右摇摆的政策变化,动辄就以腐败问题查处高官,却从来似乎不曾真正解决问题;各地大臣欺瞒,克扣军饷和如今各地防疫政策,防疫数据以及通过疫情大赚核酸检测的钱。这一系列已经发生了近 200 年的事情再一次因为病毒而重新在这片大地上演,虽然因为科技发展,生活的变化,大多数事情的发生已经改变了其面貌,以前从广州到北京的一封奏折需要一个月,现在的通信技术发展只需要几毫秒,但欺瞒的手法却如此相同,知情不报,顾左右而言他。
另外一个让我非常敬佩的是作者在文献、参考资料上的引用数量,往往看完一个章节才意识到作者的脚注竟然会多达上百个。如此翔实,具体的,从这个方面收集的材料也使得这本历史著作在学术和可信度上更加可靠。
所有想要更进一步了解鸦片战争的人。
在一些开源项目的根目录中会有一些 .editorconfig
文件,看名字也能大致猜出来是编辑器的配置文件,这个文件的主要内容就是编辑器编码、缩进等等配置。
editorconfig 可以跨不同编辑器,为不同的 IDE 维护一份一直的编码风格配置文件。
样式定义举例:
[*]
end_of_line = lf
insert_final_newline = true
第一行为通配符。
editorconfig 中可以使用正则来匹配文件,对匹配的文件使用之后定义的配置。
比如例子中的 [*]
就表示的是匹配所有的文件。
这个通配符类似正则表达式。
*
匹配除 /
之外的任意**
匹配任意字符?
匹配单个字符[name]
匹配指定字符[!name]
匹配非指定字符{s1, s2, s3}
匹配多个字符{num1..num2}
匹配 num1 和 num2 之间的任意字符。如果要指定为 Markfile 文件设定格式:
[Makefile]
indent_style = tab
也可以指定多个文件,使用 ,
分隔:
[{package.json,.travis.yml}]
如果要匹配所有的 Python 源文件和 JavaScript 源文件可以使用:
[*.{js,py}]
指定路径下的所有文件:
[lib/**.js]
indent_style = space
indent_size = 2
缩进风格:
indent_stype
可选值:
space
空格tab
Tab 制表符缩进大小:
indent_size
通常会设定 2 字符或 4 字符。
换行符号类型:
end_of_line
可以是:
lf
换行,Unix 和 Linux 下的换行cr
回车,macOS 下的crlf
回车换行,Windows 和 Dos 下编码格式:
charset
通常会:
utf-8
utf-8-bom
utf-16be
utf-16le
文件末尾是否插入空行:
insert_final_newline
如果配置 true
则在文件末尾插入空行。
常用的例子:
# top-most EditorConfig file
root = true
# all files
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# .md file
[*.md]
trim_trailing_whitespace = false
所有其他的配置可以见 官方 Wiki 。
JetBrains 的 IDEA 可以安装 editorconfig 插件。
在 Vim 下使用 vim-plug 插件管理器,添加 editorconfig-vim 插件
Plug 'editorconfig/editorconfig-vim'
source .vimrc
,然后 : PlugInstall
即可。
其他编辑器可以查看 官网 。
本文主要总结和记录一下制作和发布 torrent 的过程。
制作一个种子文件的方式有很多,熟悉命令行的朋友可以直接使用命令行制作,如果在 Windows,或 macOS 下的朋友也可以使用 UI 界面,或相关的工具来制作。
种子文件是用来维护和协调文件下载和分享的一种文件格式。这种文件通常包含了文件的哈希值(即校验和)、文件名和文件大小等信息,以及用于协调文件下载的若干个服务器的地址。这些服务器的地址被称为 trackers。
在 BitTorrent 协议中,trackers 用于协调客户端之间的文件分享。当一个用户想要下载文件时,他可以打开种子文件并把其中的 tracker 服务器地址提交给客户端。客户端会向这些 tracker 服务器发送请求,然后 tracker 服务器会返回一组已经下载了文件的客户端地址。客户端可以通过这些地址找到其他已经下载了文件的用户,并从他们那里获取文件。
在制作种子文件的过程中有几个概念需要提前了解一下:
通过命令行制作种子,可以参考 这篇文章
主要借助的命令行工具是:
通过 UI 界面制作种子一般需要本地安装一个 客户端 ,比如常用的 Transmission,或 qBittorrent,等等。
这里以 Transmission 客户端为例,来演示如何制作种子文件。首先准备需要分享的文件内容,记住其所在的位置。
首先打开 Transmission,点击左上角的 +
号,创建一个 torrent 文件。
这个时候 Transmission 会要求你选择一个文件,或者选择一个文件夹,此时选择需要分享的文件(或文件夹)。
然后 Transmission 会弹出如下的弹窗。
最后点击 Create 创建。
对于另外一些客户端,可能会要求用户选择区块的大小,如果文件大小比较适中,选择 4M 或 8M 即可,如果分享的文件内容超过 TB 级别,可以适当选择 16M 或更多。
制作好种子文件,下一步就是将种子文件分享出去。登录一个 PT 站点, 比如 GTK ,然后访问 发布 页面。
按照要求,一般在标题中填写资源的英文名称。
副标题中填写中文译名。
可以通过在浏览器中安装 油猴脚本:豆瓣资源下载大师 ,然后在设置中开启「电影简介生成」。
刷新页面,就能在词条页面中看到 movieinfo
复制该信息即可。
如果怕豆瓣图片的防盗链机制,可以将海报封面重新上传到稳定的图床。[[电影海报网站]]
电影信息查询脚本 是一个专注与通过豆瓣页面生成 PT 简介信息的用户脚本。
mediainfo 的内容一般会用 quote
代码框起来,比较美观
仅限于 Windows。本地用 PotPlayer 打开媒体文件,右击,选择属性(Ctrl+F1),然后在文件信息中,将信息复制到粘贴板。
如果发布的是原盘,可以使用 bdinfo 软件获取。
[quote] Mediainfo/BDinfo [/quote]
完成所有信息的填写,之后,点击发布。PT 站会自动重新下载一个新的种子,该种子包含了用户的个人信息,然后重载在客户端添加此种子,即可开始做种。
很久以来一直没有好好地梳理一下 Dynamic Programming 的问题,虽然 DP (动态规划)的问题一直出现,但每次遇到总是会卡壳一下。既然前人已经将这一类问题总结成一个专有名词了,那就证明这一类的问题已经可以用一套现成的模式来解决,这篇文章就整理一下 DP 问题的常见模式。下面的部分内容是看了 MIT Dynamic Programming 的公开课之后总结得出,教授用一个 Fibonacci 的问题,自顶向下,自底向上,去系统的讲了什么是 DP。 DP 就是递归问题再加上把求解的子问题结果存储「记忆」。这个教授将什么是 DP 问题一下子就解释清楚了。
动态规划是一种分阶段求解问题的思想。用简单的话归纳动态规划就是 递推+记忆。通过子问题递推出原始问题,通过额外的空间来存储子问题解。
Simplifying a complicated problem by breaking it down into simpler sub-problems ( in a recursive manner)
类似递归问题,没有本质区别,但是动态规划的区别在于,只需要存最优的状态,推导出全局最优。
DP 算法最初由 Richard Bellman 发明。DP 就是 recursion(递归) + memorization (子问题结果记忆)
DP 问题如果从子问题开始往上推导,那么就可以将递归的写法变成循环的写法。这也就是为什么在讲斐波那契数列的递推的时候,通常会有两种写法。如果已经求解了子问题,那么从下往上递推,就可以使用循环(而非递归)来求解问题了。
先来看看最经典的 Fibonacci 数列的求解方法。
如果使用递归,指数级复杂度 O(2^n)。
public int fib(int n) {
if (n == 0 || n == 1) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
但是如果引入一个数组来存储以及计算过的结果,可以进一步降低时间复杂度,从指数级降到 O(n) 的复杂度。
更进一步可以将空间复杂度也从 O(n) 降到 O(1)
public int fib(int n) {
if (n == 0 || n == 1) return n;
int[] dp = new int[2];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
int temp = dp[0] + dp[1];
dp[0] = dp[1];
dp[1] = temp;
}
return dp[1];
}
如果我们在脑海里模拟 Fib(n) 的原始求解步骤,自顶向下会发现是一棵向下的二叉树,求解 Fib(n) 首先要求解 Fib(n-1) 和 Fib(n-2),而与此同时又需要进一步求解 Fib(n-2), Fib(n-3) …….等等,并且向下求解的过程中我们会发现很多重复的计算过程。这个时候就需要看到 DP 问题的第二个特征,memorization(子问题的记忆化)。如果能够将子问题的结果保存下来,那就可以避免很多的重复计算过程。
再来看一个相似的简单爬楼梯问题,假设有一个 n 阶的楼梯,每次可以爬 1 阶或 2 阶,问有几种方式可以爬到顶。
同样如果 n 是 2,那么可以是 1+1,或者 2。如果是 n 是 3,那就可以是在 n = 2 的时候往上爬 1 阶,加上 n = 1 的时候往上爬 2 阶。
再来看看延伸一些的问题,如果在一个 m * n 的棋盘上从左上角走到右下角,每次只能走右或下,请问有多少种走法。
将原始的问题拆分为子问题:
编写伪代码:
int countPaths(boolean[][] grid, int row, int col) {
if(!validSquare[grid, row, col]) return 0;
if(isAtEnd(grid, row, col)) return 1;
return countPaths(grid, row+1, col) + countPaths(grid, row, col+1);
}
状态转移方程:
opt[i, j] = opt[i+1, j] + opt[i, j+1];
if a[i,j] is 空地:
opt[i,j] = opt[i+1, j]+opt[i,j+1]
else:
opt[i,j] = 0
5 个步骤:
如果要去学习和理解 DP 问题就必须打破原有的思维习惯,去理解机器思维,因为机器只能执行 if, while, for,条件,循环,递归等等。也必须要去锻炼拆分复杂问题的能力。
「自由」这一个词是一个非常抽象的词汇,最近这个词出现的频率越来越多,新闻自由,言论自由,信仰自由,政治自由,人们走向街头不断地呼喊自己所理解的「自由」。我们只有更好的理解我们所说的「自由」才能更有自信地去争取自由。
用英文去表达自由有两个词,freedom 和 liberty。
从这个英英的解释中我能够提取出来几个关键字,without restrictions from authority
, the capacity to exercise choice
,自由意味着免于「任何人」,「任何组织」,「任何政府」的控制,自由的人可以根据自己的意愿选择做什么,说什么。在牛津字典中给出了两个自由的反例,恰好也回答了我们为什么要争取自由,不自由的两个例子就是 prisoner 或 slave。
但上面的解释都是字面的含义,真正的自由当然不是想做什么就做什么。
[[赛亚 伯林 | 伯林]] 说,「自由的根本意义是摆脱枷锁、摆脱囚禁、摆脱他人奴役的自由。」 |
密尔在《论自由》中沿袭了密尔顿、洛克等英国自由主义传统,广泛的出版自由。密尔将人类获得真理视为绝对的善,因为获得真理可以使人进步,思想言论自由的价值并不在于它是个人的权利,而在于它能够有助于人类获得真理。
每个时代都曾持有很多被后代认为不仅错误而且荒谬的看法,可以确定的是,现在流行的很多看法将会被未来的时代所抛弃。只有经过讨论,错误的意见和行为才会逐渐屈服于事实和论证,这更一步地反证了只有思想自由才能促进社会进步。
即使我们认为我们已经掌握了真理,也要坚持言论自由,如果禁止对真理的挑战,真理就会僵化,变成死板的教条,最后丧失为自己辩护的能力。真理只有在谬误公开的冲突中得到考验,才能使真理充满活力,使大众对真理的认识更加全面、深刻。
[[霍姆斯大法官]] 为言论自由辩护,人们所希望的最终的善,最好通过思想的自由交流实现,对真理的最佳检验,在于思想在市场竞争中获得的力量。
霍姆斯认为政府没有必要,也没有能力,干预不同思想的之间的自由竞争,因为政府或者任何人都无法实现对真理的垄断。
霍姆斯甚至认为美国制度就是一场自由探索的实验,一种制度并不一直提供一劳永逸的乌托邦的思想,但可以为制度之下的人们走向真善美提供自由的机会。也只有不断的自由交流和公共讨论的过程中,这种制度才会修正错误,赢得稳定和活力。
真理自由观的问题在于,通过思想市场的自由探索是不是一定能够获得真理,或者实现真理战胜谬误。
言论在某种意义上是更好被操纵的,[[罗尔斯]]在政治自由主义中看到的那样,不能指望具有理性力量的人们,即使在自由讨论之后都达到同样的结论。
那这样真理自由的意义何在,我想最大的意义并非是能够找到某种确定的答案,而在于思想竞争和自由交流的过程本身,它们使得一个社会成为了开放的社会,使得一个人成为了开放的人,无论开放的社会有多少的问题,生活在开放的社会,总比生活在封闭的社会,对人的发展而言总要更加值得。
政治自由,通常指的是公民有权利参与到公共事务,包括选举和被选举,对权力发表不同的意见,广义的政治自由还包括上面提及的出版自由,集会自由,结社自由,游行示威自由,无罪推论。1
自由的原则成为了民主的重要途径,公共事务必须交给公众决定,这并不是因为公众的意见本身是对的,或者有见地的,而是因为公众的意见不可忽视。
民主的决策很多时候无关专业科学的判断,而只关乎利益,立场的决择,所以让每个人都发出声音,这在进行民主决策时非常重要,这样依赖, 自由本身就蕴含着平等,甚至深化了民主的平等。
自由不仅意味着随心所欲,而且意味着公共责任,民主的自由观,之所以相信自由在民主生活中的价值,还有更深刻的理由,人的天赋,条件,能力,千差万别,只有通过自由的言说,自由的实践,才能为人的才能的发挥提供最大化的机会,才能使人们更理性,更明智,更有判断力,从而减少被统治者欺骗的可能。正确的看待政府与人民的关系,并且把人们从非理性的恐惧中解脱出来,人们曾经因为害怕巫婆就烧死女人,人民曾经因为激情盲目而选择了纳粹,正如美国 [[布兰代斯大法官]] 所言,对自由的最大威胁,在于人的惰性,不鼓励思想、希望和想象是危险的,恐惧会产生镇压,镇压会产生仇恨,仇恨会威胁政府的稳定,言论自由是有风险,但是压制言论自由的风险更大。
自由对理性责任精神的强调则蕴含着民主的有限政府理念。自由的重要性不仅在于不受政府和他人的干预,更在于通过积极的行动来推进公共政策,实现利益的妥协和社会的正义。
西方社会已经认识到,词语比刀剑更有影响力。完美的社会是不可能的,但是一些秩序要胜过一些秩序。立法的任务是允许每个个人的最大自由和其他人的最大自由并存。自由必须受到法律的限制。秩序是自由的必要平衡。
当社会本身就是暴君时,当社会集体凌驾于组成它的个体之上时,暴政的实施就不限于借助政治机构之手而行的各种措施。社会如果执行了错误而非正确的命令,或者对它根本不应干涉的事务发号施令,那么它便实行了一种比其他各种政治迫害更为可怕的社会暴政,不以严厉的惩罚为支撑,但却由于更深入地渗透到人们生活的细节,束缚了人的身心,从而使人们更加无法逃脱。
从伯林对自由的分类正好可以总结出两点:
上至苏格拉底,到集大成者的康德,都强调自由代表了人的尊严和美德。人必须过一种神圣的、善的生活,没有这种内外统一的实践,人就不能称其为人,自由意志合乎道德的意志,「人是目的,而非手段」,人要理性自律,不能屈从他律。
在上一篇梳理了一下如何 注册日区的 Apple ID ,其实主要是为了这一篇整理做准备,有很多的应用,如果不是日区就安装不了,并且如果要在日本生活有一些应用还是非常重要的,所以就提前梳理一下需要用到的应用。
免责声明,因为本人此刻并没有在日本长期生活过,下面的所有内容都是我个人在搜集资料的过程中,或因本人需要,或因为其他人推荐,才收集整理得出,可能会有一些偏差,如果有读者发现任何问题,可以随时留言告诉我,我会立即修正。 另外如果有朋友长期居住在日本,平时有用到一些不错的本土应用也欢迎留言告诉我,待我尝试之后我也会补充到文章中。 希望本文可以给想要去日本旅游,或者想要去日本常居的朋友一些帮助。
要加深对日本的印象就首先从地理位置上开始认识,而城市规划,尤其是公共交通的设计,在没有用乗換案内之前我都只能在网页版的 Google Maps 上一点点得搜站点的名字,然后查看其相对的位置。
我在出门旅行也好生活也好,通常都会提前看一个这个城市的轮廓,以及集中重点的景点的位置,在 Google Maps 上用 Star 标记一下,有时间了还会用 My Maps 规划一个最优的路线,以免在陌生的地方来回重复的走回头路。
搜索 {予約 | よやく}{可 | か} 可以筛选可以预约的餐厅。 |
之前一直使用美区的账号,但突然发现有一些 App 在美区也没有,比如去日本经常需要用到的「乗換案内」就搜不到,美区里面尽是一些冒牌的,还穿插各种广告的应用,还有很多日本本地的一些应用也几乎都没有上架美区。
比如:
demo@gmail.com
,那么 demo+jp@gmail.com
, demo+hk@gmail.com
都是你的账号,Gmail 是会忽略 +
后面的内容的,另外还有一个小技巧是 Gmail 用户名中的点都是会被忽略的,所以 de.mo@gmail.com
,d.emo@gmail.com
同样也是你的账号 。那么这就非常方便了,我就用 demo+jp@gmail.com
来注册日区的账号就行了。经过以上的步骤就注册了一个没有绑定支付方式的 Apple ID 了。以后的步骤就是在 iPhone 上登录这个日区账号,并完成最后的注册。
登录成功之后就会发现 App Store 中的搜索关键字也变成日文了,热门推荐应用也变了就表示可以了。
下一篇再整理一下在日本常用的 App 吧。
另外如果有人需要日区的 Gift Card,也可以到这里 咨询购买。
另外本人开设了 日本生活记录 的新博客,如果想要了解日本的真实生活欢迎访问。
在调研个人的照片托管方案的时候,发现了一款不错的,很简洁的,开源照片展示程序 Photoview。下面就简单的介绍一下。
Photoview 是一款可以在线展示相册的应用,使用 Go 和 TypeScript 编写。
Photoview 可以将本地的文件夹变成一个在线的相册,Photoview 会定期扫描本地的文件,包括照片,视频,然后将起展示在 Web 中,Photoview 还还有一个手机客户端。
Photoview 的特性:
如果不想自己安装,那么可以通过之前我介绍的 PikaPods 来安装体验一下。注册登录之后,找到 Photoview,然后一件安装即可。
在使用的过程中,发现唯一不足的是,Photoview 正如其名,只能查看,没有任何上传和编辑的功能。