Menu Home

人类简史

CIA Error: 以下内容有剧透,请结合自身情况,自觉选择离开 或者 继续浏览 — 剧透开始 — 花了。。。好长好长一段的时间才看完这本“看过都说好”的书,但个人看下来感觉还是过誉了,精彩的部分确实不少,比如: 认知革命:单个人能维系的关系是很有限的,大概是150人左右,超出这个范围,就要靠虚构的故事来作为规范群体行为的标准 农业革命:自从人类学会了种粮食,就告别了游牧生活,形成了固定居所的部落 科学革命:否定宗教认为”上帝/主/佛主无所不知,无所不能“的观点,承认自己的无知;利益决定资源(钱,人)的分配,进而决定科技的发展方向。 最后关于智人灭亡的几种可能性讨论也很开脑洞。 生物工程:主要是通过基因实验创造出超级人类,变种人,新品种人等。代表人物有美队、快银姐弟两等。(Sorry, but X教授,万磁王他们是天生的,并不是人为实验的结果)。 仿生工程:结合人体和电子机械,如机械手臂(比如冬兵巴基、金钢狼这种),通过脑电波控制机械,甚至读取人类的大脑信息,转移到电脑上等等,他们当中目前创造出来的最厉害的是幻视。 无机生命:说白了就是奥创(话说奥创明明就是钢铁侠的锅,到最后却要队长来背,看来是背上了钢铁侠老爸的锅就放不下了啊,连儿子也要负责)。 (所以Marvel早就安排好了人类的灭亡的是吗?还设计了各种可能性!简直就是心机婊,比程心还心机婊!) 当然说它过誉,是因为个人感觉无聊的部分也不少,这从我花了这么长时间才看完就知道了。这些无聊的部分主要集中在书的第三部分,这跟你自己的兴趣可能也有关系吧。 有人说书的后半部分很主观,然而我并不这么认为,看来这所谓的主观不主观也是主观的,如果作者的观点你认同,你就会觉得”这本来就是客观实事啊,一点都不主观“;如果作者的观点你不认同,你就会觉得”这作者也太主观了,简直胡扯“。 总体来说,8.4分推荐,不能再高了,很值得看一看,但也不用给自己压力,遇到觉得无聊的部分就果断快速翻过或跳过吧。

Elm语言初体验

这个周末两天一直在看Elm,这是一门函数式编程语言。所谓函数式编程(Functional Programming,FP),跟面向对象编程(Object Oriented,OO)是同一种类型的概念,是一种编程模式。具体什么叫函数式编程,它有什么特征,有什么优势,这里不作具体解释。只放出一个大胆的预言,就是在未来,尤其是在Server端,将会是函数式编程的天下。 Anyway,Elm是一门函数式编程语言,它是一门静态的,强类型的语言,目前主要targeting在Web端,因此它有一个compiler可以编译成JS。 目前,编译成JS的语言已经有非常多了,如CoffeeScript,TypeScript,PureScript等等,甚至很多现有的general purpose语言现在也有了一些工具,用来把它们编译成JS,如Clojure 有ClojureScript,Scala有Scalajs,Ruby有Opal等等等等。 为什么有这么多的新语言编译成JS,又有这么多工具把其它语言编译成JS呢?这些说白了其实都是想取代JS,这说明一个问题,那就是JS不够好,这个跟JVM上面有这么多语言原因是类似的。 Elm也是出于同样的原因,它想要发明一种全新的Web语言,用于取代JS。那在这么多语言中,Elm的优势是什么? 经过这两天的接触,我了解到它的优势有以下几个: No Runtime Error。”Undefined is not a function” 有没有遇到过?如果你做过一段时间前端开发,你不可能没有遇到过这个问题。类似的Runtime Error还有非常多。然而,Elm声称可以完成避免Runtime Error!这绝对是无可比拟的一个优势。美国的一家公司NoRedLink声称,他们的产品上线一年多,目前遇到的Runtime Error是0个!这个还是非常有诱惑力的。 纯粹的函数式编程,Immutable data和pure function,让你的代码变得干净,0耦合,不易出错,容易重构,易读,易测。这些都是JS界目前大力推进的方向啊,不然要immutable.js干吗?要Ramda干吗?要RxJs干吗? 有一个“官方”的App architecture,这是一个非常优秀的architecture,有多优秀?Redux大家都知道,现在其实已经是Web app实际上的标准architecture,然而Redux的思想其实是从Elm的architecture学来的! 总之,我觉得这个视频里面有一句话总结得非常好,那就是Elm是现在整个JS界的发展趋势,然而JS还有很长一段路要走。 那Elm完美的吗?当然不是,我这两天接触下来,发现它仍然处于比较年轻的状态,虽然官方声称它已经production ready,也确实有好一些公司已经用于正式的产品中。然而我相信都不是很容易的事情。目前来说,我觉得有以下几个问题需要极需改善: 社区太小,这可能是目前最大的问题,在国内更是如此。如果你在百度上面搜”Elm“,出来的结果基本都不是Elm语言相关的。当然这也不赖Elm,因为你在百度上搜其它东西,基本出来的结果也不是你想要的。 函数式编程与OO或过程式编程差别太大,上手真不是很容易,这会在很大的程度上影响到它的采用率。 Elm语言和编译器本身也有一些东西有等完善,如目前还不支持String interpolation,elm reactor(类似于webpack-dev-server)不支持hot reload,其实之前是支持的,后来发现了bug,就去掉了。Time travel debugger也是,本来是有的,后来发现有bug又去掉了。当前这些都不是很严重的问题,比如hot reload只是节省了你手动刷新页面的功力而已。然而从这些”原来有,后来发现有bug又去掉“这些事情中就能说明这个东西还不是很稳定的问题。 接下来打算在公司的内部小工具上面试用一下,因为Elm文件是可以跟JS交互的,所以应该不是太大的问题,大不了再用回JS嘛。但是函数式编程作为未来的发展趋势,还是要了解一下的。所以,总体来说,我觉得这是一门非常值得学习的语言。 如果你对Elm感兴趣,欢迎加我微信(875156226),共同交流。

买颗星星送给你

如果在你临死前,突然给你三百万,你会做什么呢? 很久很久以后,有个人——我们叫他小明吧。用现代话(在他看来应该是文言文)来说,小明是个典型的”屌丝“。单身,工作不是非常顺利,也没什么朋友。这倒不是他性格有什么问题。。。哦,他性格确实比较孤僻敏感,但这倒不是因为他人品有什么问题,只是从小的经历让他有了现在的一些性格。 他出身于一个知识分子家庭,受的是贵族的教育,然而由于父母都没有什么社交能力,他们家庭的物质方面比较贫寒。因此一直生活在社会底层,自然接触的都是社会底层的人,然而因为他从小受的是贵族教育,他打心眼里对这些人有一些排斥心理,自然无法跟这些人建立起深厚的关系,因此从小到大都没什么亲密的朋友。感情方面则更加不用说,大学毕业之前,他都没跟女生说过几次话。这仅有的几次跟女生接触,是一个非常美丽善良、温柔漂亮、对任何人都很好的女生。自从第一次接触,那个女生就如阳光般温暖了他的整个心灵,女生也就这样在他心里永远的扎下了根,让他就这么一直暗恋着暗恋着暗恋着。。。 家庭方面呢,也不和睦,父母在他上初中的时候离异了,他和姐姐跟了父亲,现在父亲身体不好,一直是姐姐在照顾,自然姐姐会有怨言,因此姐弟关系也不算好。 但现在这些都不是事,如今有更加重要的问题摆在他面前,那就是,他得了绝症,肺癌,癌细胞已经扩散到全身了。也就是说,他现在是一个将死之人。 令人讽刺的是,在这个时刻,他突然得了一大笔钱,是怎么来的呢?原来很久之前,在跟仅有的几个谈得来的朋友谈话过程中,偶然间给了他朋友一个启发,他朋友根据他的这个idea,制造出了一种饮料,结果卖得非常好,发了大财。这位朋友也是个有良心的人,为了回报小明,给了他三百万。 现在停下来想想,如果你在他这种情况之下,你会拿这笔钱做什么呢? 好吧,我知道你肯定很想知道小明用这笔钱做了什么。小明做的事情是,他拿这笔钱给那个他一直暗恋的女生买了一颗星星。是的,在他这个年代, 这确实是个浪漫的故事,如果你觉得好像在哪看过这个故事的话,不用怀疑,这就是三体里面的故事,小明就是云天明,女生叫程心。我只不过一时兴起,想要复述一遍而已。 如果你不怕剧透的话——其实剧透了也没关系,这个故事只是三体故事中一个小小小小的插曲——我想说不幸的是,这个故事我们都只猜到了开头,没猜到结尾,在接下来的故事里面,事情并没有像我们想象的那样历经千辛万苦,最终浪漫的结束,小明和小程Live happily ever after,而是女生一个人多次毁灭世界于希望之中,最后只剩下她和另外一个高富帅逃离到星际之外去了。 —全剧终—

标准GNU命令行的格式

我们每天都在Terminal下面运行很多命令,但是,你了解一条命令的标准格式吗?对于我来说,以前并没怎么关心过,都是拿来就用,不会就google。这几天继续看《Build Awesome Command-Line Applications in Ruby 2》,其中讲到了GNU规定的命令行的格式,看完以后有种恍然大悟的感觉,才发现原来一条命令还有一个标准格式的,有了这个格式,很多东西都不用记了,一个命令用起来就觉得有章可循了,对一个不熟悉的命令,也更容易猜到,或是找到使用的方法。 废话不多说,一个GNU规定的命令行的格式如下图所示: 一个完整的Terminal命令主要由4部分组成: 命令名(Executable): git 子命令(Command): push 选项(Options): –no-pager 和 -v都是 参数(arguments): origin和master 这里重点是选项(Options)的一些格式规定。 选项根据形式分类 从形式上来说,Options有两种形式:简短形式和完整形式。 简短形式一般由一个连接符“-”后面跟一个字母组成: ls -l -a -t # -l, -a, -t都是简短形式的Option 其实,几个简短形式的options可以合并写成一个: ls -lat 效果等同于 ls -l -a -t 完整形式的则一般由两个连接符“–”开头,接着是一个或多个完整的单词,如果有多个单词,那么中间用一个连接符连接,如上面的“–no-pager”。 选项根据功能分类 从功能上来讲,Options一般有两种。一种的是“switch”(开关),用来enable或者是disable(一般以“–no”开头)一些feature,如上面的–no-pager,就是用来disable pager这个feature的。除此之外的另外一种是flag。switch一般没有参数,flag则一般有参数。 如果一个flag有参数,那么一般简短形式的flag跟它的参数之间由一个空格分开。而完整形式的flag则用一个“=”连接它的参数,如: curl -X POST http://www.google.com #POST是-X的参数 curl […]

什么叫"功能单一"

昨天开始看《Build Awesome Command-Line Applications in Ruby 2》这本书,看完第一章。其中提到一个Awesome的Command,应该是功能单一(single-purpose)的,但是具体什么叫功能单一呢?为了解释这个问题,书中举了两个反例,来解释什么不是功能单一。 第一个例子是一个备份数据库的脚本。其中需要备份的数据库有两个,这个脚本一次性把两个脚本都备份了,脚本大概是这么写的: #!/usr/bin/env ruby # File: db_backup.rb #两个数据库的信息 databases = { big_client: { database: ‘big_client’, username: ‘big’, password: ‘big’, }, small_client: { database: ‘small_client’, username: ‘small’, password: ‘p@ssWord!’, } } databases.each do |name,config| #依次备份每个数据库 #… end 使用的时候,只需要运行一个这个命令就好了。但是这个脚本的结构其实并不好,也并不是"功能单一",之所以这么说,是因为它一次性备份了两个数据库,而不是一个。试想一下,如果后来又有一个数据库需要备份,那么就得改这个脚本,修改上面databases这个Hash(Map、Dictionary,whatever)。这个可不是一个好主意,如果别人给你一个备份数据库的脚本,然后你说要再备份一个数据库,结果他说你要改那个脚本,这时候你的感觉可不会太好,如果这个人离职了呢?如果他用的是一门你不熟悉的语言写的呢?如果他用的是write-only的perl写的呢? 所以对于这个脚本,更好的组织方式是,脚本本身只备份一个数据库,并且需要的数据库信息是从外面传进来的。 比如可以这样写: #!/usr/bin/env ruby # File: db_backup.rb […]

Rails Authentication From Scratch

这是一个对railscast250的学习笔记,所有copyright belongs to Railscast作者 Ryan Bates ### 1. 创建User Model rails g resource user email password_digest 这里有两点说明,一是关于rails g resource,你可能对rails g scaffold熟悉,那resource是什么呢?在这里,scaffold和resource都是rails generator,就是可以帮你自动生成很多琐碎的东西的助手,这样你就不用自己一遍一遍写类似的东西了。resource跟scaffold最主要的不同是,resource不会帮你生成对应的controller里面的任何个action以及他们对应的任何view;第二点需要说明的是“password_digest”这个字段,这个字段比较关键,因为接下来我们要用到rails为我们提供的has_secure_password这个helper method,这个method默认需要用到这个字段。 ### 2. Migrate database 在命令行执行rake db:migrate创建你的database ### 3. 打开model里面的user.rb,加上 has_secure_password class User < ActiveRecord::Base has_secure_password end has_secure_password这个方法我们前面提到过,它的作用是,利用前面提到的password_digest字段,给你提供password 和password_confirmation两个字段,并帮你做一些常见的validation,比如:密码不能为空,长度必须小于72字符,把password和password_confirmation两个字段进行对比,确保他们相等,等等。 ### 4. 安装bcrypt gem 前面提到的has_secure_password这个方法需要用到一个gem叫bcrypt,这个gem在你创建project的时候默认已经加到你的Gemfile里面去了,只不过默认被注释掉了。我们打开Gemfile,找到那一行并uncomment掉。接着执行 bundle install 进行安装,安装完这个gem以后,重启rails server让它生效。 […]

安卓单元测试(十一):异步代码怎么测试

这是被问得最多的问题之一。。。 问题 今天讲一个我们讨论群里面被问得最多的一个问题:怎么测试异步操作。问题很明显,测试方法跑完了的时候,被测代码可能还没跑完,这就有问题了。比如下面的类: public class RepoModel { private Handler mUiHandler = new Handler(Looper.getMainLooper()); public void loadRepos(final RepoCallback callback) { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); final List<Repo> repos = new ArrayList<>(); repos.add(new Repo("android-unit-testing-tutorial", "A repo that demos how to do android unit testing")); mUiHandler.post(new […]

Android单元测试(十):DaggerMock:The Power of Dagger2, The Ease of Mockito

The Old Way 我们在系列的第六篇文章前面介绍了Dagger2在单元测试里面的使用姿势。大致过程是这样的,首先,你要mock出一个Module,让它的某个Provider方法在被调用的时候,返回你想到的mock的Dependency。然后使用这个mock的module来build出一个Component,再把这个Component放到你的ComponentHolder。举个例子说明一下,假设你有一个LoginActivity,里面有一个LoginPresenter,是通过Dagger2 inject进去的,如下: public class LoginActivity extends AppCompatActivity { @Inject LoginPresenter mLoginPresenter; @Override protected void onCreate(Bundle savedInstanceState) { //…other code ComponentHolder.getAppComponent().inject(this); } } //对应的Test类如下: @RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class LoginActivityTest { @Test public void testLogin() { AppModule mockAppModule = Mockito.mock(AppModule.class); LoginPresenter mockLoginPresenter = mock(LoginPresenter.class); […]

安卓单元测试(九):使用Mockito Annotation快速创建Mock

注: 如果你还不了解Mock的概念或Mockito框架的使用,请先看这篇文章。 @Mock的基本用法 如果你follow了这个安卓单元测试系列文章,那么到现在为止,你应该很清楚mock的概念和使用了,创建Mock的方法我们都知道: YourClass yourInstance = Mockito.mock(YourClass.class); 比如: public class LoginPresenterTest { @Test public void testLogin() { UserManager mockUserManager = mock(UserManager.class); PasswordValidator mockValidator = mock(PasswordValidator.class); Mockito.when(mockValidator.verifyPassword("xiaochuang is handsome")).thenReturn(true); LoginPresenter presenter = new LoginPresenter(mockUserManager, mockValidator); presenter.login("xiaochuang", "xiaochuang is handsome"); verify(mockUserManager).performLogin("xiaochuang", "xiaochuang is handsome"); } } 虽然很简单,但是如果一个测试类里面很多测试方法都要用到mock,那写起来就会有点麻烦,这时候我们可以写一个@Before方法来作这个setup工作: public class LoginPresenterTest { […]

安卓单元测试(八):Junit Rule的使用

JUnit Rule是什么 一个JUnit Rule就是一个实现了TestRule的类,这些类的作用类似于@Before、@After,是用来在每个测试方法的执行前后执行一些代码的一个方法。 如果你不清楚@Before、@After这些Annotation的意思,Chances are你还不了解Junit的使用,建议先看这篇文章。 那为什么不直接用这些annotation呢?这是因为它们都只能作用于一个类,如果同一个setup需要在两个类里面同时使用,那么你就要在两个测试类里面定义相同的@Before方法,然后里面写相同的代码,这就造成了代码重复。有的人说你可以用继承啊,首先我想说,我很讨厌继承这个东西,所以如果可以不用继承的话,我就不会用;再次我想说,如果你不讨厌继承的话,从现在开始,你也应该慢慢的讨厌它了。 此外,JUnit Rule还能做一些@Before这些Annotation做不到的事情,那就是他们可以动态的获取将要运行的测试类、测试方法的信息。这个在接下来的一个例子里面可以看到。 怎么用JUnit Rule? 使用框架自带的Rule 很多测试框架比如JUnit、Mockito自带给我们很多已经实现过好了的JUnit Rule,我们可以直接拿来用。比如Timeout,TemporaryFolder,等等。这些Rule的使用方法非常简单。定义一个这些类的public field,然后用@Rule修饰一下就好了。比如 public class ExampleTest { @Rule public Timeout timeout = new Timeout(1000); //使用Timeout这个 Rule, @Test public void testMethod1() throws Exception { //your tests } @Test public void testMethod2() throws Exception { //your tests2 } //other test […]