Hegel2011的博客

读书 - 工作 - 生活 - 笔记

java新的兼容性挑战者Kotlin

520期间被刷屏的除了show 恩爱,就是Kotlin了。 原本只是在一个做安卓的小朋友发的pdf里看见了Kotlin,想想应该又是一个和scala groovy或者closure类似的东西— 可以跑在jvm上,能利用jdk的库,语言表达力又强于java。

Java尽管有点啰嗦,语言表达力确实一般,但企业级的支持很强,jvm的性能更是出色,所以在类库、ide、甚至大型开发框架方面是无与伦比的。在jvm上跑的语言很多,甚至想部分替代的如scala closure groovy等等都火过一阵子,但是java继续维持着自己的优势地位。

然而这次真正被刷屏的,是因为Google认了Kotlin为干儿子,甚至以后可能是亲儿子,将kotlin变成了 头等安卓开发语言。查了一下,此前获得此定位的仅有java,这就可能有很大的不同了。kotlin有了google的支持,而其他所谓挑战者可没这个干爹。并且,Kotlin的创建者又是目前最流行的java ide的公司贡献的,可以保证在开发工具上的体验和支持,这么看来它的优势就比scala等强多了。

希望还是能帮助java改进吧,当然这个有点难,即使java8好几年下来了,也不知道有没有普及率超过java程序员的50%

Thymeleaf感想

刚使用spring boot时得知thymeleaf取代了jsp的默认地位,我是有所抵触的,做法就是重新配置回了jsp。 然而随着java web开发前后端业已分离的现实,逐步明白view层是thymeleaf还是jsp已经不再重要。因为java已变成 服务成守候在服务器侧,而原先页面的工作已经完全交给了(不需要会java)的前端人员,且他们是完全可以胜任的。

实际上截至目前,最新版的thymeleaf已经到了3.0以上的版本,而spring boot最新版集成的还是2.x的thymeleaf的版本, 可以认为这块已经处于冷淡的状态。

不过,凡是总有例外。这次又碰见了需要产生静态页面的业务场景,其中有不少的业务逻辑,所以还是需要一个view层,考虑到 新团队的习惯,决定采用thymeleaf吧,这样以后维护可以交给前端来做。于是简易学习了一下leaf,感觉还是不错的。

leaf最大的特色就是前端人员可以直接打开leaf所在的html页面,并做到完全的无异物感。脚本、链接完全动态静态可以分开。 这样解决了jsp长期以来美工介入很困难的问题,同时做的又比freemaker等更加到位。内置标签支持的语言语法也很现代化和好用,一般有jsp经验的程序员, 花个半天看一下一百来页的手册并动手实践一下,就完全可上手了。至于jsp,是可以退出历史舞台了。

Truffle and Solidity

区块链应用的开发,主要指用Solidity编写合约(Contract),然后部署到区块链上去。 注意,此处的区块链特指以太坊,而比特币的区块链是没有Solidity这种东西的。

因为是把sol编写的合约部署到区块链上去,所以可以进一步分解为3个问题:

  1. 区块链的安装(testrpc ethereum)
  2. sol合约编写(Solidity)
  3. 对sol合约进行编译以及发布(truffle)

目前来看,整个以太坊很喜欢借用node即javascript来构建他们的环境,尽管区块链和sol本身其实和javascript关系不大。 关于ethereum可查相关的安装手册,这里主要记录一下Solidity和truffle。

Sol的编辑器可以用atom vscode等等,submiline也没问题。 这门语言其实还是比较原始的,合约间的调用甚至不能传递结构(struct),更可悲的是返回string也不行。基本上任何不定长的返回 在sol的ethvm(以太坊虚拟机)中都不太好调用。 功能上来讲,solidity可以理解成数据存放在一个类似levelDB的内存数据库,这是ethvm会做的事情。

1
2
  mapping(uint=>LibDisSecPledgeApply.DisSecPledgeApply)  disSecPledgeApplyMap;
  uint[] disSecPledgeApplyIds;

上述代码定义了一个用于存放对象数据的mapping,因为mapping无循环遍历的功能,所以又增加了一个ids的数组保留所有对象的编号。

整个合约的编写,其实对写惯后台程序的人来讲还是不难上手的(类似用java操作redis写业务逻辑),只是限制确实比较多。 但solidity可以支持的变化太少,所以写起来是复杂不到哪里去。相当于成熟的脚本或编译型语言,solidity麻烦的地方在于其调试, 可简单罗列的就有两点:

  1. 编译速度慢。十几个文件的情况下,用 truffle编译就要3分钟以上
  2. 发布调试困难。必须发布到某个链的环境才能测试,而这个就真的很不友好了,断点还不支持,日志也很麻烦。

truffle是现在以太坊主要推荐的编写solidity的编译、测试运行和部署工具,能处理较复杂的sol文件关联引用,就是耗时很长,且 程序版本很不稳定,变化发展都依然极快。truffle是基于node和npm的,所以要先装好node。

1
2
3
4
5
npm uninstall truffle
npm install -g truffle@2.1.2
truffle compile  //编译合约
truffle migrate --reset //部署合约
truffle exec xxxx.js //执行某个js文件

和区块链一样,solidity,truffle都是刚刚涌现的东西,所以问题很多,用起来也不一定顺手。但,这个行业就是这样的。

CA证书略记

CA是Certificate Authority的缩写,就是一个证书颁发机构的意思。 它的作用是给某些公钥证书进行背书,以让调用者相信所获得的公钥证书确实的某个组织给予的。

具体做法可抽象为:
1. 某个组织自己生成一个公钥/私钥对
2. 该组织向某CA申请证书,需要把自己的身份信息、公钥交给ca,同时用自己的私钥给以上信息签名形成一个CSR,格式可以说pkcs10等
3. CA生成证书,比如P7b格式的证书。

此后,该申请的组织就可以把获得的证书交给客户,客户会去CA处验证证书的有效性等。

在现实中,浏览器、手机等默认内建很多知名CA,可能有几百个,对于这些CA颁发的证书均认为是安全的。

上述只是颁发完毕,之后进入使用阶段。

公钥与私钥的理解:  (1)私钥用来进行解密和签名,是给自己用的。
 (2)公钥由本人公开,用于加密和验证签名,是给别人用的。
(3)当该用户发送文件时,用私钥签名,别人用他给的公钥验证签名,可以保证该信息是由他发送的。当该用户接受文件时,别人用他的公钥加密,他用私钥解密,可以保证该信息只能由他接收到。

数字签名的基本用法

由于私钥加密东西长度是有限制的,所以一般私钥只用于对内容散列后的签名。 比如SHA1withRSA,顾名思义就是SHA1散列后用rsa加密散列值。

公钥端收到后,可对散列值进行解密,解密后再和收到的数据进行散列操作后的结果进行比对,如果散列值一致,那么该签名就是有效的。

区块链功课

https://www.igvita.com/2014/05/05/minimum-viable-block-chain/

Google的工程师讲解的P2P去中心化现金交易的底层技术—区块链(Block Chain),然后发现区块链的一大基石 是公钥私钥的加密技术,所以作者拿出了经典的Alice Bob来作为举例。

中心化的支付技术

目前的支付系统流行的是triple-entry 记账方式。三联为Alice Bob 和Chuck(中心节点,比如银行)都记录着交易记录, 以保证交易的可靠性和非重复性。 这套系统运作的前提是大家都信任Chuck。

去中心化的难点

1. 一致性问题

去中心化后,系统变成了分布式的,而分布式在一致性方面先天弱于中心化的。处理Double-spending的问题是一个难点。 因为一个交易发生后,系统中的其他参与者往往并不知道已经发生,可能还认为Bob拥有大量的钱财。在一个小的系统里, 可以通过全部完成通知后才认可交易成功,而这对一个大规模系统基本不可行。CAP理论表明P2P系统很难支持强一致性,但是,区块链技术 的亮点在于实现了weak(er) consistency。

2. Sybil attacks (西比尔攻击)

该攻击的特色在于虚拟出许多虚假的交易者,让真实的交易者误以为消费已经坐实。解决办法是增加造假的成本,同时保持验证的 成本够低,通过经济杠杆来从结构上阻止有人愿意造假,因为得不偿失就是傻事了。

但这带来的一个问题就是单个交易成本会很高,如果交易的手续费高于交易本身,那么这套系统也是没法运行的。

Block的概念

Block就是一组交易的集合,不单如此每个Block还记录了前一个Block,从而构成了Block Chain区块链。 每个交易者都可以将有效的交易集合生成一个block,生成block需要耗费大量的计算资源。 而将验证成本集中成Block的好处就是降低了每笔交易的成本,或者说交易集合共同承担了手续成本。而对交易有效性的、一致性、Sybil attacks的 防范都基于Block来进行。

Block Chain的冲突

因为所有的参与者都可以生成Block,所以一笔交易可能会加入在多个Block里。此时就构成了冲突,出现了chain fork。Block Chain对此的解决方式很简单粗暴, 永远选择最长的那个chain fork作为“真实的”交易链,并丢弃之前的交易分支。

使用的技术都是现成的:

  • accounting
  • cryptography
  • networking
  • proof-of-work

然而集合起来就又构成了一个新的精巧的方案。

Zookeeper

用于协作的服务,提供目录树的结构。基本可以认为是Yahoo出品。

data registers - called znodes, file parlance - directory

数据全部保存在内存中。

优势: 1. 性能好,可在大规模的分布式系统里使用 2. 可靠性高,可防止单点故障 3. 严格的顺序性,可满足复杂的、高精的客户端同步实现要求

znode的读写有acl控制以及版本号

leader nodes负责接受写的请求,follower nodes负责被同步和读取

配置示例

1
2
3
4
5
6
7
8
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

tickTime是一个即使单元,单位是毫秒,2000表示2秒。
dataDir是存放数据文件的物理位置。
initLimit表示n个tickTime,上面这个就是10秒的意思,表示连接上leader nodes需要的时间单元数量。
syncLimit表示山离皇帝能有多远过期
server.1中的1的服务器内部的myid,zoo1是服务器地址,第二个port即2888用于follewer连接leader, 第三更port 3888用于选举leader。

基本上,zookeeper可以理解成一个分布式系统里,用于进程间通信的中间件,所以剩下的就是客户端调用了。 项目本身提供了C和Java的binding,具体实现时每个客户端会分为IO线程和watch线程两个。而Netflix在此基础上, 构造了wrapper: curator,以方便开发。

首先,引入maven依赖:

1
2
3
4
5
<dependency>  
    <groupId>org.apache.curator</groupId>  
    <artifactId>curator-recipes</artifactId>  
    <version>3.2.1</version>  
</dependency>

然后,在代码中可如下调用:

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
package zookeepertest;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;

public class CuratorTest {

  public void set() {
      String zookeeperConnectionString="127.0.0.1:2181";
      RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
              CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);


              client.start();

              try {
                  client.create().forPath("/my", "555".getBytes());

                  client.getData().forPath("/my");
                  Thread.sleep(1000);

                  client.setData().forPath("/my", "666".getBytes());

              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
  }

  public static void main(String[] args) {
      CuratorTest test = new CuratorTest();
      test.set();
  }
}

这种调用方式是比较原始的进程间通信,以此为基础,recipes已经实现了一系列通信的高级语意, 如lock、semaphore、确认leader等,可以直接使用。

DIY的好处以及雨刮和滤芯

用车两年多,有两个地方始终不太让人满意:1.雨刮器 2.空调滤芯。

个人还是比较喜欢开雨刮的,所以雨刮用的比较费,原厂的也就半年就会变花了需要更换。 之前用国产品牌carall直接替换,第一次效果还是不错的,用了4个月才花的比较厉害。 于是又去买了一对。但第二次的体验就很差,突然感觉噪音变得很大。可能小厂的品控比较差,质量高高低低的。同时,carall的价钱倒是涨的快。弄来弄去又回到了换胶条的路子上。

很早搜索论坛就得知换胶条是最经济实惠的,无奈需要diy,感觉这么个东西也没多少钱,所以最早选择 直接买了。但随着直接替换不令人满意,而且考虑到只换胶条的话,等于还能保留并继续使用原厂的雨刮臂。更重要的,本田确实是个很有意思的公司,在手册上竟然也是推荐换胶条的,并给出了怎么换的图例和说明。实际上本田的4s只卖胶条,雨刮臂很难买。于是决定自己换胶条。

自己DIY雨刮胶条之后,感觉还是很不错的。首先是成本低了很多,因为这是替换方式上形成的成本优势。只换胶条而不换雨刮臂当然比换整支雨刮臂成本低,而老化和变花的只是胶条,雨刮臂的寿命其实很长。 一对胶条的成本只在12-18元之间,一对雨刮的国产也要30-40。其次,效果方面毕竟是原厂的钢条支撑,声音就正常许多了,清晰度其实起初用用都还行。这东西关键还是在于要勤换。终于找到了一个效果、成本、难易程度都让自己满意的方案。而这一切的关键就是要DIY。

然后,最近买了几款车用空调滤芯。

  1. 韦斯特带炭
  2. 高仿本田原厂
  3. 博世不带炭
  4. 博世带炭
  5. 马勒带炭

用下来么基本还是先看滤芯结构,结构相同的情况下一分价钱一分货。 不带炭的博世是最差的,生产日期超过一年半的韦斯特也是大幅衰减的。 然而,如果给它们都盖上HEPA滤纸,可能效果就会都好很多。而这也是diy在 架构方面的胜利。

虽然购买服务是商业社会的主流选择,但DIY永远有其使用的空间。 一来社会化生产的服务归根结底也要来源于diy,二来总有社会服务提供不到位的地方也需要diy,三来补锅法锯箭法也需要diy来进行对冲。

Included file 'twitter_sharing.html' not found in _includes directory