Zeco CX6 投影仪刷固件

我一直以为刷固件离我很远,昨晚 CX6 开机之后就一直停在了开机画面,重启数遍无效,找到客服,说要刷固件,当时哪个场合太囧了!第一次拿到别人家里放,N 双眼睛等着看新玩意,结果告诉我要!刷!固!件!

好吧,那就现场刷一下吧,又遇到一件囧事,CX6 背后的 micro USB 插口深不见底啊,普通 5mm 长的嘴插进去就掉了,好吧,那就用手按着吧,根据说明一步一步,结果还是不停显示出错了,出错了…… 打电话问技术支持,当时是晚上 10:10,得到的消息是插头不够长,建议我削掉一点胶。

明显是又一个很不合理的设计,我找了 N 根 micro USB 的线,全部都是最近一两年的机型配的原装数据线,嘴都是 5mm 的,CX6 的要至少 6mm 长的才行,问题是都知道自己的特殊一点,就配一条 6mm 的嘛。虽然技术支持说可以邮一根过来,但是时间就太长了。

好,扯远了。准备好工具之后,就开始动手削!可能要牺牲一根华为的线了。

削线需要的工具

先把头部的胶削掉 0.5mm ,试了一下,还真不行,再削 0.5mm,都见到里面的“骨头”了,已经不能削更多了。上天保佑终于可以了。

露出 6mm

刷固件就难在,要先拿个牙签桶住 RESET 按钮不妨再开机,如果你习惯用右手的话,最好用左手去桶,不解释了。然后就没有什么难度,打开软件,选择一下固件来源,跟着都自动完成。

左手桶 RESET 键

烧录完成

至于为什么 CX6 会变砖,跟马航事件一样目前没有定论,不过最大的嫌疑是 App 更新造成的。App 自己都提示更新是修复已知问题,架构上是应该不会影响到系统无法启动的,关于这一点,得到的建议是不要点 App 自己的更新,呃…… 有骗小白的嫌疑。

这不说软件在稳定性上完全跟不上了,说说外观设计。同样是插头,HDMI / VGA 的就比较浅,至少外面就能看到,OTG 接口就不能再伸出来一点点么?同样的 TF-CARD 的,卡已经够小了,手指粗的人能塞卡进去,但是如果想取出来,你得有长指甲,注意是要长指甲,刚剪过的会够不着。底部的进风口距离固定点太近,三脚架的快装板多少会遮住一点。我认为,接口少一点其实更加好,可以更加专注提升软件质量,做接口其实还要考虑接口做工的可用性,至少用来急救刷固件的接口要确保场合适应性。

思维的陷阱

前阵子遇到个问题,是在 Joomla 里升级组件的时候出现 “Failed to copy file” 的错误。我已经习惯了先 google 解决方案,跟随头几个方案,都说是文件或文件夹权限的问题,我满心欢喜地以为已经接近真相了。

几小时过去,哪几个文件夹,包括父文件夹都已经变成 777 了,还是一样报错。然后,开始想是不是姿势不对,还有几个可疑的地方,包括是不是应该先删除旧的组件,然后新安装;不要用上传 zip 包的方式,而改用直接用服务器上的文件进行安装;改用 ftp 的方式进行安装等等。多得有 git ,每次尝试完一种办法不可行之后,所有文件都可以恢复到初始状态。不过多次尝试未果之后,隐约觉得有点浪费生命了。

几天过去了,中间也重复过之前的尝试,每次都有一点点变化,希望找到突破口,也向身边的同行咨询,尝试过各种跟权限有关的方法,依然是未有进展。

事情开始变得吊诡起来。

又几天过去,浪费生命也得有个谱,思维才开始跳出这是一个权限问题的框框,立刻动手写了个小脚本,放在同一位置,用最简单的 API,对同样的文件进行操作,结果是令人震惊的,毫无权限问题。然后开始跟踪代码,系统比较大,对源码结构不是很熟悉,花了点时间才最终确认,由于一个程序配置的问题,导致文件复制的步骤总是返回失败。触摸真相的感觉依然是让人兴奋的。

回头再想,如果早一点开始翻查源码,会不会就能早点发现事实呢?

但问题是,为什么不早一点。

是因为这个陷阱太完美了么?还是因为自己的思维出现固定模式,感觉到同样的问题一定已经有不少人遇到了,而且很可能都已经解决了,只是还没有搜索到而已。源代码与搜索引擎这两个工具,我潜意识会更多地使用的是搜索引擎而不是源代码。也许是因为搜索引擎很多时候能更快的给出答案,不需要太多的思考,而阅读源代码注定要花比较多时间,要记忆流程思考其中的逻辑。问题不在于工具本身,而在于人在什么位置出发思考问题。

还有另外一个因素是时间,急于解决问题,于是求助于通常能快速解决问题的搜索引擎,越是急,越会优先选择快速方案而不是思考正确的方案。

Google Webmaster 索引历史丢失 (已解决)

刚刚发现一个奇怪的事情,下午的时候,Google Webmaster 里一个站点的索引历史好好的,还给别人看索引趋势,刚才再去观察的时候就全都没了。

被吓得赶紧用 site: 指令搜索一下,还好索引还在。只是历史丢了,也没收到什么警告邮件之类的。难道只是一时的数据丢失?

希望这些数据认得路回家。

===== 华丽的分割线 =====

Update: 睡了一觉之后,重新进入 Webmaster 里查看,站点地图里的编入索引数量和历史已经回来了,但是索引状态那里却依然是一条直直的线。

如下图↯
Google 索引显示为 0

Update: 经过一周之后,终于看见索引历史的曲线了。这个数据的更新周期大约是一周至二周,所以频繁的去观察这个数据是没有多大意义的。只要 sitemap 里索引数量正常就可以了。

可维护的代码?

今天被问了一个很有意思的问题:(Lisp 的)代码真的可维护么?(这里的维护,意思比较泛化,包含一般性的代码改动,甚至重写。)

缘起我在微博写道 “Noir 是个好东西”。NoirClojure 的 web 框架,而 Clojure 是 Lisp 的一种方言。看过《黑客与画家》的人应该知道 Lisp 是多么的光芒万丈,但同时又被很多人所厌恶,真是超典型的矛盾统一体。不过这里不打算讨论这个矛盾。将上面的问题转换一下之后是:

代码的可维护性跟语言有关吗?

我觉得有关,但这只是基于当前现状的。像 Lisp 这么小众的语言,应用到项目当中,技术人员一拨一拨的流动时(这也不算是一个好的现状,不利于自身的积累),如果想一直都能找到合适的人来做,这本来就已经是一个问题。在国内,许多不是技术驱动的公司里,几乎很难碰到会使用小众技术解决问题的(所以如果你遇到了没有这样的氛围却依然坚持不懈的玩各种小众玩意的,千万不能随意放手啊),技术选型的其中一项是团队里或者市面上都流行什么。但如果不存在人口基数的问题,代码的可维护性应该是跟语言没什么关系的。

代码的可维护性跟什么有关系呢?

架构。因为像可维护性,代码演进这些问题是架构设计的时候考虑的。代码书写的风格,代码的组织方式,资源布局,运行机制与策略等等这些都会有影响。除了架构,有洁癖的通常会比无洁癖的产出更容易维护的代码(写得烂不烂的问题是可以通过学习改进的),代码整洁整齐,用法一致也便于维护。

按照我的猜想,应该是可以使用 Noir 并产出可维护的项目的。

回到语言细节上,因为很多人接受不了那一连串的括号,总是第一感觉以为要人肉去数哪些个括号,特别是N多层嵌套的时候,和这个类似的,nodejs 推广过程中也好多好多个声音说 N 层回调嵌套看着头晕。

我有必要再解释这个问题么?如果反过来问,一个语言能给你带来的价值减去其缺点所造成的损失结果是多少?这不代表我承认 Lisp 或者 JavaScript 的缺陷有多大,有多招人讨厌,而是想说,我们能否正确认识其价值,放大其价值。

哪些语言被创造出来最大的幸福是其价值得到显现。当然,价值这东西很难拿出来讨论,自己心里明白就好。

也许在最大化其利益之后,那才是踏踏实实的讨论改正缺点,但是有时候,比如 Lisp 的括号(列表表达式),最大的缺点也正正就是最大的优点,最好的办法是,当没看见吧。

@符号在 Chrome 里的奇怪显示

在处理首页一些细节的时候发现,在 Windows 上的 Chrome 显示 @ 符号的时候有些异常:

通过和上面一个 @ 对比即可发现下面一个更加窄一些。

为什么会有这么一个奇怪的现象呢?

想起前几天看的一篇博文 浏览器如何渲染文本,里面说到,在进行文字排版之前,会有个 text run 的过程,会根据一些语言规则,产生出一些 shaper,然后才是交给后续排版。 Continue reading

Chrome 总提示需要更新 Flash Player

前阵子用 Google Chrome酷容,原谷歌浏览器,这名字还需要一段时间去适应)的时候就发现它老会提示需要更新 Flash Player,按照它的提示安装了最新的 Flash Player Plugin,依然是老样子,当时没时间折腾就没理它。

更新了 Ubuntu 到 1204 之后,发现问题依然存在。又重新安装了 Flash Player Plugin 好几次,其实在 Firefox 里已经看到是最新版本了,但为什么 Chrome 认不出来呢?

根据 Adobe 上的文档 的提示。打开 chrome://plugins/,点击在右上角的 Details 按钮,查找 Flash 那一项,奇怪的是里面显示有 2 files。

一个是 位于 ~/.mozilla/plugins/libflashplayer.so 版本是 10.3 d162,另一个位于 /usr/lib/adobe-flashplugin/libflashplayer.so 版本是 11.2 r202,于是尝试 disable 了第一项,重启 Chrome。

OK,问题解决。

余下的问题就是,为什么 Chrome 有这样的机制存在?既然有更加高版本的插件存在,为什么不是首选更高版本运行,而是简单地按顺序拿第一个版本来运行,并且打开凡是包含 flash 插件的页面都提示需要更新,即使安装了最新的也依然提示,很让人摸不着头脑。

更换了 syntax highlight 插件

其实是个遗留问题。之前是用 Google Syntax Highlighter for WordPress,用起来也还不错,只是有些时候贴写 bash 代码,或者终端里的回显信息时候,真不知道该使用那种语言来显示高亮好。

直到最近开始写有关 Lisp 的 状况系统 与 异常处理 时,发觉情况有点糟糕啊,高亮结果都乱套了。然后跑到它的项目主页去找解决办法,看看有没有别人已经做好的扩展,或者看看怎么自己去扩展一下。结果是比较让人失望的,连怎么扩展的说明没有,也不寄望能找到现成的了。

但似乎又不能怪它,人家已经在主页上写了“This page is OLD, Head over to http://alexgorbatchev.com/wiki/”。那似乎是个更好的解决方案。然后又 google 到了 WP SyntaxHightlighter (在 wordpress 插件库里有一大堆名字很类似的插件,需要点眼力,或者精准查找)。这个插件所使用的正是它。这个插件支持多种配色方案,更吸引我的是下面有列出已经有人做了 Clojure 的扩展(Clojure 是 JVM 上的 Lisp)。

换插件是很容易的,admin 里点几下就搞定了。问题剩余两个:

  1. Clojure 扩展不是原生支持的,需要自行添加到插件中去
  2. 原有 post 里面的 <pre> 标签都需要做些修改,由 class=”lang” 改为 class=”brush: lang”

PHP 我不是很熟,不过靠猜,找到了一个文件(wp-syntaxhighlighter.php)里面有类似支持语言的数组,照例子改了下上传。一开始还不行,后来搞清楚了,它会保存选项到数据库里面,reset 一下就好了。

第二个问题没想到什么批量的办法,花了些时间,顺便把以前写的 post 都重温了下,虽然看得人不多,评论也不多,但是这些都是很好的见证。想起曾经有个时刻,大家都会开个 blog,还很认真的写过一阵,还都写得不错,有观点,有感情。相比之下,我在语文表达障碍阴影底下,只会写些技术文章来凑个热闹。

而随着热潮的退却,大家好像被 reset 了一样,也没有人写个告别博客什么的,只是不再写了。过程是缓慢的,没有人会感到不舒服,不会像断奶,学行走,上学,毕业那样会有许许多多的思想冲突发生。它连个状态切换都不是,只是一种变化跟随。大概无须要为这种事情赋予个什么意义,有人会选择做,有人会选择不做,但如果选择了做,请尽情享受那个过程。

我也作出了选择,我会继续追随梦想,分享美好的瞬间,分享独立的思考,这里是我的梦想飞行器。

Flex SDK 几个版本之间的关系

http://opensource.adobe.com/wiki/display/flexsdk/Downloads

一开始看总有点茫然的,怎么有三个下载链接?
Free Adobe Flex x SDK | Open Source Flex SDK | Adobe Add-ons for Open Source Flex SDK
到底是哪个跟哪个?
页面上方有几段文字,是被我skip掉了,里面有写三者之间的关系
基本就是 license 的区别。

Adobe Flex SDK 是包含开源和闭源的组件。
Open Source Flex SDK 是仅包含开源组件
Add-ons 则是闭源组件

可以简单的理解为
Adobe Flex SDK = Open Source Flex SDK + Adobe Add-ons for Open Source Flex SDK

可以根据自己的版权需求和应用需求的情况去选择

一个斜杠引起的思考

最近关注 WebService,尝试CXF的一个 Client 样例 时,修改一下,运行,总是报这个错:
Caused by: java.net.MalformedURLException: Invalid address. Endpoint address cannot be null.
……

本来想跳过它了,但是很简单的修改,如下

public static final QName SERVIVE_NAME = new QName(
		"http://ws.leegorous.net", "Hello");
public static final QName PORT_NAME = new QName(
		"http://ws.leegorous.net", "HelloPort");

public static void main(String[] args) {
	Service service = Service.create(SERVIVE_NAME);

	String endpointAddress = "http://localhost:9000/hello";
	service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING,
			endpointAddress);

	Hello srv = service.getPort(Hello.class);
	System.out.println(srv.sayHi("Leegorous"));
}

感觉离真相很近,但怎么都搞不着的感觉真是糟糕~

于是开始调试,调试一下也不错,可以顺便大概了解下过程,但是越挖掘,越觉得奇怪。小说电视里,经常吹嘘当找不到方向时不妨回到原点,这个的原点就是我修改的部分。

很奇怪的发现样例里初始化QName的第一个参数是以”/”结尾的,我想不会吧。
一边质疑着自己,一边加上斜杠,运行测试,居然成功了!

public static final QName SERVIVE_NAME = new QName(
		"http://ws.leegorous.net/", "Hello");
public static final QName PORT_NAME = new QName(
		"http://ws.leegorous.net/", "HelloPort");

已经找到步向真相的入口了。或许是QName的问题,也可能是后面使用它的程序有问题,具体还有待解剖报告。

这个问题貌似不太值得一写。不过它使我想起昨晚发现的一起事件,某报文系统已经运行了数年,但居然还有比较低级的解析失败,而且最糟糕就是搜索过分依赖于那个出错的属性。而据我观察,好些系统问题都是有各种各样的“小”而且不太可能发生的失误而造成的,也正是大家都不是仔细收集和分析证据,而是先入为主的否决了其些可能性转而去思考所谓的更大可能性,而浪费了大量的时间。

不过有些先入为主的印象作用是我们不能左右的,就如现在人们在介绍我时依然是用类似于“一个Web界面高手”,甚至是“美工”,除了无奈,还能做什么呢?

难道跳出来大叫
“That’s so 2007”

!##$%^&*()~~