Month: July 2014

  • 爱因斯坦:科学家、政治独立者

    看了Walter Isaacson的《乔布斯传》,写了几篇评论,决定再看他写的另一本伟人传记:《爱因斯坦传》,书籍全名是:Einstein: His Life and Universe。

    前几天和老彼得闲聊的时候,我说,其实爱因斯坦的狭义相对论中所用到的数学知识你现在已经全部学过了。也就是说,狭义相对论牵涉到的数学模型其实只停留在初中数学层次。他听后的反应是很不明觉厉。

    爱因斯坦到了普林斯顿后,就再也没有离开过美国,在学术上也再没有任何值得称道的成就。他的精力全部投入到至少在目前看来仍然毫无希望的统一场论中。驱使他这么做的是他一生信奉的理念:

    Nature is pleased with simplicity.

    他极力反对量子论所提倡的不确定性——该不确定性可以简单的归纳到一句话:上帝掷骰子吗?

    对于爱因斯坦而言:

    For some people, miracles serve as evidence of God’s existence. For Einstein it was the absence of miracles that reflected divine providence. The fact that the cosmos is comprehensible, that it follows laws, is worthy of awe. This is the defining quality of a “God who reveals himself in the harmony of all that exists.”

    对某些人而言,奇迹是上帝存在的证据。而爱因斯坦认为,正是奇迹的不存在,才体现了上帝的天意。宇宙是可被理解的,它遵循法则,这一事实值得敬畏。“上帝在万物的和谐中展现祂自己”的要旨也就是如此。

    ========

    物理史上有两个“奇迹之年”(Annus Mirabilis)。1666年的牛顿,他在那年提出了微积分、运动学、光学、引力方面的开天辟地的工作。1905年的爱因斯坦,他在那年提出了光电效应、布朗运动、狭义相对论以及最著名的公式[latex]E=mc^2[/latex]。当然,爱因斯坦后来在1915年继续提出了广义相对论。但是自此之后,爱因斯坦也就在物理上没有值得一书的新成就了。还是那句话:

    因为按照羊皮纸手稿的预言,就在奥雷连诺.布恩蒂亚译完羊皮纸手稿的最后瞬刻间,马孔多这个镜子似的(或者蜃景似的)城镇,将被飓风从地面上一扫而光,将从人们的记忆中彻底抹掉,羊皮纸手稿所记载的一切将永远不会重现,遭受百年孤独的家族,注定不会在大地上第二次出现了。

    爱因斯坦如此,他在普林斯顿最好的朋友、最平等的朋友哥德尔也是如此。

    =============

    20世纪的物理学的标记是三个“性”——或者说三个“定理”、“原理”:

    爱因斯坦的相对论,海森堡的不确定性原理,以及哥德尔的不完备性。(Einstein’s relativity, Heisenberg’s uncertainty, and Gödel’s incompleteness.)这三样东西都有着其深刻的哲学内涵。

    =============

    爱因斯坦常以“犹太人”自居。由此出发,定义了他的政治倾向。他彻头彻尾反对的是对自由的限制,崇尚的是不守常规。他的这一个性实际上也直接影响了他的学术研究:在绝对时空当道的时候,他发明了相对论;在量子论势如破竹所向披靡的时候,他固执地选择统一场论。我相信,与他同时代的人以及我们这些后人,一定会禁不住的设想,如果爱因斯坦早早抛弃他那不靠谱的统一场论,而与哥本哈根学派联手进行量子论的研究,他又会有怎样了不起的突破和成就呢?但是,我们也明白,如果爱因斯坦那么做,那么他也就不是爱因斯坦了。

    Creativity required being willing not to conform. 创造力需要的是刻意不去遵从。 The development of science and of the creative activities of the spirit requires a freedom that consists in the independence of thought from the restrictions of authoritarian and social prejudice. 科学以及其它创造性精神活动的发展需要的是自由,它包含在思想的独立性中,并不受权威和社会偏见的约束。

    ==============

    我的世界观和爱因斯坦接近。最近读过的《上帝掷骰子吗?》只能让我对量子力学不明觉厉,细思恐极。我是相信一定有终极理论的。这个世界一定是由确定性的规律主宰,而不是随机性。这也是我的政治主张和立场。

  • 解决git push时出现的https错误

    (本文收录于[go4pro.org])

    这两天更新了一点我的“任氏有无轩“站点,结果发现无论是使用命令行的git还是SourceTree,都无法push到远程repo,出现错误如下:

    Ashampoo_Snap_2014.07.26_09h38m21s_001_

    在网上查了一下,基本上都指向Windows搜索一个DLL——本例中是libcurl.dll——的路径优先问题。

    按照MSDN官方的说法是:PATH变量中设置的路径是要到很后面才会被搜索到的。于是我在Windows命令行中开始搜索所有的libcurl.dll文件,发现归于Windows系统目录下的有三处:

    Ashampoo_Snap_2014.07.26_09h43m27s_002_

    经过试错法,确定在我的Windows 8.1 64位版中,最后一个libcurl.dll需要被替换(注:需要admin权限才可以替换系统文件)。支持https的libcurl.dll的大小应该是360448字节。

    然后再次git push,无论是在命令行还是SourceTree中都可以了。

  • PHP开发者经常会犯的另外7个错误

    本文原始链接:7 More Mistakes Commonly Made by PHP Developers。作者:Bruno Skvorc

    Thanks for Sitepoint.com authorization for translation and publication in my blog.

    本文翻译力求忠实原始文档。

    ==========译文开始分割线==============

    在6月的时候,TopTal(自由编程人员市场)发表了一篇文章,题为《PHP程序员最常犯的10个错误》。那个列表当然不是穷尽的,但确实写得不错,并指出了一些非常有趣的、值得每个人关注的陷阱——即便如我个人都不会将这些错误认为是很常见的。

    我希望你对这篇文章加以通读——其中有一些确实很有价值的、你需要知道的信息,特别是前八个要点。几天前,Anna Filina扩展了这个列表,并加入了七个新的项目。尽管这些地方不那么特定也不那么常见,她的观点还是有分量的,需要在开发时加以考虑。

    PHP开发者经常会犯的另外7个错误

    TopPal中某位仁兄请我看看他们的列表,还有没有补充,社交网络上的一些粉丝也表示有兴趣看到这个列表继续。所以,我愿意借此机会在这个列表中加入我自己的一些事项。这些都是我不断需要去警示我的团队或者粉丝们的。

    1. 使用mysql扩展

    这个消息其实很旧了,但是尚未注意这个事实的开发者数量还是大到令人担忧。如果用到SQL数据库,特别是MySQL,有太多的开发者还是倾向于使用mysql扩展。这个扩展已经官方认定过时。它不安全,不可靠,不支持SSL,不支持MySQL中的一些现代特性。它也会产生过时提醒,出现在你的应用的最顶部——但不会中断应用。滑稽的是,这意味着我们可以简单地Google这个关键词,就能找到大量这样还是用着这一不安全设置的站点。因为这个,这些应用所面对的伤害是令人震惊的。

    避免使用mysql,我们可以选择:MySQLi或者PDO。例如,使用MySQLi简单到几乎只要在API调用后加一个“i”即可:

    $c = mysql_connect(host, user, pass);
    mysql_select_db(database);
    $result = mysql_query(SELECT * FROM posts LIMIT 1);
    $row = mysql_fetch_assoc($result);

    对比:

    $mysqli = new mysqli(host, user, pass, database);
    $result = $mysqli->query(SELECT * FROM posts LIMIT 1);
    $row = $result->fetch_assoc();

    使得我们的设置变得更安全,所要做的就是这些。 不过你应该选择PDO。详见第2点。

    1. 不使用PDO

    不要误会,mysqli确实(确实确实)比古老的mysql扩展超出了好几代。它更新及时,安全,可靠,快速。但是,它只适用于MySQL。使用PDO可以让你使用一些美妙而实用的面向对象语法,也能让你做好准备使用另外的SQL数据库(如PostgreSQL,MS SQL以及其它)。另外,PDO可以让你使用命名参数。这一特性非常有用,只要充分利用它带来的好处,就很少有人能想象不这么做。最后,还有这点:你可以直接将获取的数据注入到一个新对象中,对于大项目而言,这能节省时间,而且是令人愉悦的。

    1. 不重写URL

    这是一个常常被忽略却也容易修正的问题。诸如myapp.com/index.php?p=34&g=24这样的URL如今简直就是不能被接受的。由于几乎不可能写出一个好的URL重写规则来涵盖每个服务器和框架,几乎每个框架都有一个指南,告诉我们如何设置干净的URL(Laravel, Phalcon, Symfony, Zend)。如果哪个框架不这么做,那么它就不值得我们使用——这些框架显然不关注现代化的实践。

    1. 抑制错误提示

    我在以前的一篇文章中写过这个问题,但还是有必要再说一说。任何时候你发现自己使用@运算符,请再考虑考虑,尝试从另一个角度更认真地处理这个问题。用我的话来说,在一个应用的功能中包含20行引用的cURL代码也比单单一行前放一个@来的好。

    我个人的经验告诉我,我在原来的帖子中建议的方法是一个好方法:打开所有的提示并转化其为致命错误。要确保在错误日志中没有任何记录,因为确实没有要记录的东西要比用@遮在眼前,装作看不见有错误发生要好。

    最近我们发现了一些Heroku add-ons可以用来开发生产环境下的PHP应用,其中一个Papertrail很棒。这个add-on让你将应用所有的错误推送到后台,从而可以轻松的加以搜索、分组并在日后加以清除。所以,即使真的有错误发生,让它们被记录下来,然后通过修订代码来消除错误。这比抑制它们,愚弄你的用户来的好。

    1. 条件判断中的赋值

    即使再有经验的程序员有时也会手指一滑,写下if ($condition = 'value') {而不是if ($condition == 'value') {。我们的手会打滑,键盘可能没有记录按键,我们从代码的另一部分——那一部分确实进行的是赋值操作——拷贝了代码。这些都有可能,而我们只有在运行应用时才发现问题。

    要完全避免这个问题,有几个方法:

    • 使用一个好的IDE。任何好IDE(比如PhpStorm)会在检测到这一问题时警告说”条件判断中进行了赋值“。
    • 使用“Yoda Conditions”。在众多流行项目,甚至大型框架中,都会看到这个应用。通过交换比较双方(if ('value' = $condition) {),即使比较弱的IDE也能注意到这个问题。有人认为Yoda语法很讨厌而且毫无意义,其信条是绝不使用(“更小心地编码,蠢货!”)。单就个人而言,如果能帮到你的话,我是建议使用的。如果我们都是优秀人物,那么WordPress和Zend Framework就不会存在了。
    • 牢牢记住,每次写的时候都要检查一次。所要的知识练习,但即使对于最好的开发人员而言,这也可能发生。所以前两点会有用。
    1. 太透明了

    我这么说可能会有反对意见,不过我还是要说。除非你对框架的开发者有100%的信心,或者也不运行高利润、高流量的商务关键应用,你应该总是努力隐藏你的后台——不要告诉大家你的应用基于什么框架。这实际上能对防止攻击起到作用——如果发现了该框架的一个安全漏洞的话。例如:

    If you use Symfony2 translator and have a route with a {_locale} parameter upgrade NOW http://t.co/jihXHB8MzT— Jérémy DERUSSÉ (@jderusse) July 15, 2014

    在该Tweet中,有关代码注入的一个严重问题已经变成了广为人知的知识。如果你正在上班,可以立即升级而不用担心开发问题或者让团队停止,那很好。但是对大部分使用Symfony的人和公司而言,情况不是如此。即便Symfony可以通过Composer升级(如Ryan在评论中提到的那样),在大的多层环境的团队中,通常这要花一些时间来获得批准。所有使用这一翻译机制的站点,并且也声明了是Symfony的用户的站点,就会面临该缺陷,直到被修正。

    上面提到的使用Symfony,只是一个例子。多年来,类似的情形发生在无数其它的软件中。我还在使用ZF框架开发商业应用那会,也发生过这样的情况,并因此受到了攻击。WordPress也有其安全性漏洞,而我们也知道世上有多少站点是由它来运行的。会发生这些事情。有时,开源和透明不是最好的方法来处理那些承担公司主要收入来源的应用。

    1. 没有移除开发配置

    最后,我要提一提移除开发配置。最近(声明,我再次提到Symfony纯粹是巧合),Cnet遭受了一次攻击,原因就是没有移除它们的开发配置。

    Uhmmm no: http://t.co/rAQis1ycWq #security #symfony— Marco Pivetta (@Ocramius) July 15, 2014

    Cnet是全球最大的技术新闻站点之一,它基于Symfony。你可能知道,Symfony有两个应用入口:app.php和app_dev.php。你的浏览器访问其中之一,进入的是生产环境,如果访问带有_dev后缀的那个,显然你会进入开发环境,从而有除错器、敏感数据以及诸如此类。这样是好是坏可是很多讨论的话题(再次感谢Ryan指出了这点)。但无可否认的是,它让一些比较笨拙的开发者面临着Cnet面临的同样的错误。另外,通过app_dev访问的任何其它URL也会导向其它的app_dev相关的URL。换句话说,不仅是首页在开发环境下运行,而是整个站点——放在Cnet的案例中,这可是大量的访问。

    如果你跟踪了Twitter上的讨论,情形很快就糟糕到令人尴尬——而更可悲的是,只要几秒钟的工作就可以避免:

    • 开发者应该在生产用服务器中删除app_dev.php
    • 开发者应该将可以访问app_dev.php的IP放入白名单,这也是缺省配置——除非你故意放松了这些限制

    任何一个方法都可以完全避免所有的问题。记住,在发布到生产环境时,要确保你的开发配置要么完全不可访问,要么只有在白名单中的IP可以访问。

    结论

    (本文收录于[go4pro.org])

  • 一本需要严肃对待的喜剧

    《布达佩斯大饭店》是一本需要严肃对待的喜剧。

    豆瓣上对此的解读有很多,比如对M. Gustav的解构以及他与茨威格的关联,对《苹果的男孩》的解读,有对“永远回不来的昨日世界”的感慨,有对“怎样才是一个真正的绅士”的判定。

    08年的时候我看《巨人传》,写了一篇书评:一本需要严肃对待的闲书——评《巨人传》。我觉得,《布达佩斯大饭店》也是这么一本需要严肃对待的喜剧。

    故事的主线很简单,围绕着去世女伯爵夫人的遗产争夺,M. Gustav陷入了一个阴谋。被陷害、入狱、越狱、逃亡、洗清罪名、死去。

    正是这故事的展开和拍摄手法具有着浓烈的古典浪漫主义的味道。

    几个细节:

    • M. Gustav对Zero如何花销那五块钱的教诲;
    • M. Gustav不能离身的香水,名为L’air de Panache;
    • M. Gustav明明有alibi,却不愿意提供,只是为了对方那位女子的名誉;
    • 巨搞笑的越狱桥段;
    • 巨搞笑的缆车桥段和前往修道院和Serge X见面的桥段;
    • 巨搞笑的滑雪追凶桥段;
    • 靠着Mendl\’s蛋糕混入酒店的桥段——还重复了两次!
    • 火车两次意外停靠,以及Zero在火车上两次被宪兵质询,以及M. Gustav两次为Zero挺身而出——一次成功了,一次他付出了生命。

    也就是说,在一切可能违背我们常规意识的前提下,情节得以展开。但是我们还是看得津津有味而且觉得意犹未尽。

    导演显然不想让我们悲哀,于是淡化了一切可能牵扯到暴力的东西——两个例外,一个是Agatha姐姐被砍下的头;一个是律师的四根断指。

    所有的一切都在轻松愉快的铺陈中展开,再加上观众们早已有心理准备的“主角光环”,一切的一切都那么轻松愉快。大量长镜头的使用,也渲染了这样的氛围。

    直到最后,是的,直到最后。当Zero再次面对宪兵队的质询并要被带出列出,M. Gustav再次挺身而出,Zero回忆起M. Gustav说的那句最著名的台词:

    You see, there are still faint glimmers of civilization left in this barbaric slaughterhouse that was once known as humanity.

    可是,此时的画面早就变成了黑白色,而不是第一次这样的场景中的彩色。对《辛德勒名单》的致敬注定这第二次类似的冲突必然是悲剧。

    M. Gustav死了,欧洲的文明也死了。M. Gustav财产的继承人是Zero,而欧洲文明的继承人何在?

    ===============

    由一本书引起一个故事,而这个故事又是由书中的两人面对面讲述,这样的手法是不是很熟悉?

    ================

    面对着对人性的undoing(茨威格语),最理性的理性就是没有理性。我们有办法逃离而隐世,就像M. Gustav和Zero、Agatha准备做的那样?回答的是悲观的。M. Gustav只是为了能保留这野蛮人的屠宰场里最微弱的一个称为“人性”的闪光点,却付出了生命的代价。

    The beginning of the end of the end of the beginning has begun.

    M. Gustav和Zero等在酒店外面时,前者对后者如是说。

    什么已经开始?开始的结束的结束的开始。这个回文似的隐喻给我带来的不只是冲击,也有着明悟。

    任何时刻,任何发生,都有着起承转合。有开始的,有结束的。结束的开始,意味着新的开始已经进入了结束的进程。在某种意义上,有点“凤凰涅磐”的含义。

    凤凰自知将死,就会自焚,而灰烬中最后一颗火星殒灭之时,就是凤凰再生的开始。

    在这个意义上,导演更像是为欧洲的文化新一轮的复兴发出了第一声的呐喊。Those good old days.

  • Dart 1.5.3的一些变化

    Ashampoo_Snap_2014.07.15_22h13m10s_003_

    Dart是一个发展非常快速的语言。如今最新的版本是1.5.3。自从今年1月份我写了两篇关于Dart的文章( )以来,Dart语言本身,尤其是我用到的Polymer部分,有了很大的变化。

    为了准备8月9日(暂定)于苏州举行的,由G4P.ccGDG Suzhou联合举办的活动,我对之前编写的Dart小程序进行了调试。本文就在这次调试中发现的变化进行一些总结。

    一个Dart/Polymer程序的架构没有变化,还是由三部分组成:

    • 入口程序,比如getqotd.html。这个文件提供了页面的布局和对Polymer元素的调用。
    • Polymer元素模板,比如qotd.html。这个文件定义了一个Polymer元素的布局和一些基本设置。
    • Polymer元素的代码,比如qotd.dart。这个文件也是该Polymer元素的驱动代码部分,也可以是我们编写的一个Polymer/Dart程序的核心。

    入口程序

    <head>
      <meta charset=utf-8>
      <meta name=viewport content=width=device-width, initial-scale=1.0>
      <title>QOTD Sampe App</title>
      <script src=packages/web_components/platform.js></script>
      <script src=packages/web_components/dart_support.js></script>
      <!-- import the qotd -->
      <link rel=import href=qotd.html>
      <script type=application/dart>export 'package:polymer/init.dart';</script>
      <script src=packages/browser/dart.js></script>
      <link rel=stylesheet href=css/bootstrap.min.css>
    </head>

    这是一个标准的入口程序的HTML头部分。与之前相比,该部分加入了移动设备的支持。

    另外,所引用的JS文件也改为platform.jsdart_support.js。而原来的:<script type=application/dart>export 'package:polymer/init.dart';</script><script src=packages/browser/dart.js></script>已经被弃用。我个人对这个改变比较欢迎。毕竟原来的语句很不像HTML。

    模板

    重要的改变有两个。

    一个是在原先的<polymer-element>定义之前必须再加一个<link rel=import href=packages/polymer/polymer.html>语句。

    第二,鉴于Dart已经重新对shadow DOM进行了更好的支持,于是可以在<template>中直接加入对CSS的引用,如:<link type=text/css rel=stylesheet href=css/bootstrap.min.css>这样。

    代码

    鉴于上述的第二点,代码中原先需要的对shadowDOM进行applyAuthorStyles的操作就不再必要。事实上,如果你写了,Dart编译器会给出deprecated的警告。

    基本上我发现的改动就是这些。当然,改动肯定不止这些。我在O\’Reilly买了一本Dart: Up and Running的书,电子版已经更新并专列了一章介绍新的变换。我印象比较深的是Reflection的引入。

    本文收录于[go4pro.org]