《3 idiots》观后感

2010年8月7日 ColorHook 2 条评论

3 idiots是朋友@sammyliang力荐的一部电影,豆瓣上的评分也很优。看了之后感受到该片的艺术价值不小,紧密连贯的故事情节、前后铺垫的表现手法,美轮美奂的音乐舞蹈,还有深刻入微的人生哲理,都给人带来了丰富的视听享受,是值得墙裂强烈推荐的。

《肖申克的救赎》中有说生活中很多时候就是例行公事,因为平淡而深刻。回想一下,我们从小学到初中,从高中到大学,很多事情都形成了一种模式,一种游戏规则。每个人都要遵循规则,不遵循规则就会被视为异类,就会遭到抵制和扼杀,这是一种体制化。我想我们每个人都会有梦想,或者最初有梦想,但是经过10多年的“体制化教育”后,还有多少人触及的到那个梦想。大概梦想早就被融化,掠夺和取代了吧,剩下的只有吃饭,睡觉,打豆豆,岌岌于生,岌岌于死。

未经审视的生活是不值得过的,苏格拉底如是说。我们都希望生活的好,但是这个太难了,难的不是目标达不到,反而是目标太不明确了。每个人对“生活”的定义不一样,对“好”的定义又不一样,你认为这是生活,别人不同意;你认为这是好的,别人不赞同;更不巧的是我们往往把目标挂靠在持不同观点的人身上,直接抹杀了自己优秀的人生观和思想成果。摈弃他人不合理的看法吧,多多思考自己所经历的,所要经历的才能为自己的生活明确方向,明确参照物,而把参照物定位到别人身上都将是危险的。

有时候习惯了亦步亦趋,思考能力也就退化了。体制化是这样一种东西,一开始你排斥它,后来你习惯它,直到最后你离不开它。我想我得重新思考起来了,做一个有思想的人,不是为了与众不同,而是人生需要它产生勇气。

发布as-spring 2.4

2010年8月4日 ColorHook 没有评论

ActionScript作为一个编译型(解释+编译)语言,经常需要把一些变量存在外部文件中,如XML文档。但是经常去解析XML文件就不是一件令人愉快的事情,而且变化点不是String, Number等基本类型的话,解析完XML后还要做更多的事情,于是as-spring诞生了。

as-spring是我的一个基于Flash平台的类库,作为一个Ioc反射框架,它在平时工作中给我带来了很多便利。我以前有过几篇博客提到过它:

  1. 在ActionScript中使用简单的Spring框架来实现IOC
  2. 使用Spring来配置RemoteObject
  3. 发布as-spring 2.1

这次升级加入了部分新的特征,用来消除使用过程中遇到的一些不便之处。具体特征如下:

1. 简化基本类型的数据类型定义

以前定义一个Bean都是用<bean>标签来定义,如果我要定义一个String类型的Bean,需要这样来定义:

<bean class='String'>
    <constructor-arg value='This is a String'/>
</bean>

现在可以用<element>标签来定义:

<element value='This is a String' type='String'/>

2. 增加了数组定义

以前定义数组没有好的方法,特别是当数组的元素不是基本类型时。现在可以用<list>标签来定义:

<list id='arr'>
    <element value='true'/>
    <bean>
    </bean>
    <list>
    </list>
</list>
3. 增加了Hash Object的定义

这个功能其实在以前就可以很方便的实现,只是现在加入了一个更符合思维的定义方式:

<map>
    <key name='apple' value='[iPhone,iPad]'>
    <key name='google'>
        <value>android</value>
    </key>
    <key name='ms'>
        <list>
               <element value='XP'/>
               <element value='Vista'/>
               <element value='Win7'/>
        </list>
    </key>
</map>

本来打算加入对flash.utils.Dictionary的定义的,最后还是放弃了,主要是因为暂时没有遇到迫切需要Dictionary的应用场景,如果以后遇到了,可以考虑加入这个功能。

使用ActionScript更新{新浪微博}

2010年8月4日 ColorHook 没有评论

新浪微博作为一个微博应用在国内还是比较流行的,至少我周围的人就有很多是她的用户。由于新浪微博开放了类似twitter的API, 所以有一部分推友使用了twitter至新浪微博的同步脚本,这里我想使用ActionScript来更新一个新浪微博。

通过API来更新新浪微博有一个前提条件,就是需要注册成为sina的开发者,并创建一个应用还获得一个app key。这些不在详述,具体请参考新浪微博官方站点。获得app key后就可以开始使用ActionScript来正常调用相关API了。

这里我没有使用号称相对安全的OAuth方式登陆,而是使用更直接的Basic Authorization来通过验证,下面是完整代码:

//Define parameters
var username:String='新浪微博用户名';
var password:String='新浪微博密码';
var source:String='新浪微博app key';
var API_URL:String='http://api.t.sina.com.cn';  //新浪微博API domain
var status:String='需要更新的状态';
 
//define HTTP request
var encodedCredentials:String=Base64.encode(username + ":" + password);
var authHeader:URLRequestHeader=new URLRequestHeader("Authorization", 
                                               "Basic " + encodedCredentials);
var url:String = API_URL+ '/statuses/update.xml';
var request:URLRequest = new URLRequest(url);
var variables:URLVariables = new URLVariables();
variables.source = source;
variables.status = status;
request.data = variables;
request.requestHeaders.push(authHeader);
request.method = 'POST';
 
//send HTTP request.
var loader:URLLoader=new URLLoader();
loader.addEventListener(Event.COMPLETE, onLoaderComplete);
loader.load(request);
 
//HTTP response
function onLoaderComplete(e){
    trace (e.target.data);
}

这里只用到1个外部类Base64,用于HTTP请求中对用户名密码进行加密,该类可以从as3crypto类库中获得。

下载Base64外部库后,设置好正确的classpath,然后替换相关参数,执行代码来更新你的新浪微博吧。

have fun!

Windows下配置gedit笔记

2010年7月18日 ColorHook 没有评论
下载gedit for Windows

gedit作为Ubuntu默认的编辑器轻便快捷,简单易用,得益于插件机制,扩展起来也很方便。加上Zen Coding的支持,把它作为前端开发的IDE是十分合适的。Windows下的binary版本可以这个网址找到:http://live.gnome.org/Gedit/Windows.

安装Zen Coding插件

Zen Coding是快速开发HTML/CSS的一种方式,如果没听过Zen Coding?这里有介绍,还有Google Code上的wiki。为gedit准备的插件zen-coding-gedit可以从github下载。

安装ActionScript, MXML和GLSL语法高亮插件

gedit集成了很多语言的高亮显示,但是默认没有支持ActionScript,打开as文件或mxml文件却看不到花花绿绿的颜色,这是很难令作为Flash开发者接受的,如果有Flash方面的开发需求,相关的高亮插件可以在 http://conic.se/blog/posts/8/下载。

有待增强的地方
  • 文件关联需要去安装路径浏览exe文件
  • 许多插件无法使用
分类: Develop & Design 标签: ,

辞职之工作杂感

2010年7月11日 ColorHook 3 条评论

这周拿到了离职证明,离开了呆了近21个月的公司BrightCreek, 一家以人为本,以创造力为盈利筹码的高新企业。在过去的1年多,我见证了公司的发展和变更,参与了各种各样的软件项目,写过各种各样的程序语言。

想当初在20世纪五六十年代,那时候的程序被记录在打孔卡片上,我从来没有见过这种卡片,但是听说那时候的程序非常严谨,不仅精简,而且优美,出错极少。因为当时运行程序的代价十分昂贵,有限的主机时间需要预约,所以程序的返工和修改都是不应该发生的。那时候的软件开发如同神话一样充满了传奇色彩。

反观今日,程序的编写不再那么难以进行,打开电脑就可以轻易地进行软件开发,Windows,Mac OS, GUN/Linux各种操作系统下都有成熟的IEDIDE, 软件开发不再那么遥不可及,甚至任何人都可以通过简单的拖拽动作来完成了一个软件界面。但是如今软件的质量不再那么可靠,软件崩溃愈演愈烈,软件垃圾愈来愈多,项目经常被延期,挂起和终止,而造成这一现象的原因却着实令人费解。

我开始回忆在所做项目中自己有用到的语言,印象中有ActionScript, HTML, CSS, JavaScript, PHP, ColdFusion, Java, C#, SQL, 其中JavaScript这块用到的Ajax库有jQuery, Ext, Mootools, Dojo. 想到这里,我也略微知道项目经常失败的原因了:当项目中重要的部分由不称职的人担当着是极其危险的

某种语言出身的程序员会被投入到另一种语言相关的项目中去,这种情况经常会发生,不是发生在别人身上,就是发生在自己身上。刚开始该程序员会本着依赖于原有程序的思维模式去写新的语言,加上不熟悉新语言的API,写出惨不忍睹的程序真是太容易了,更加杯具的是,这个时候要是没有一个老鸟在旁边指正指导,对于该程序员和项目都是一种灾难。从成本价值的角度去分析,这是一次失败的投资战略,程序员花了时间和精力去越过一条陡峭的学习曲线,得到的只是三流的经验;项目在前期表面上进行的顺利,中后期将越来越杂乱,最后变得难以维护。

如果不幸你成为了上面那个程序员,我想说的是:请寻找正确的学习途径,切忌盲目操刀,不求甚解。

项目遇到缺少专业人员的情况时,最有效的对策应该是找一个合适的人。招人简单吗?很不简单。至少从实际效果上看是这样。招一个自己满意甚至准满意的人都是十分困难的。我面过6、7个前端的职位(是能立马做事的那种),却发现没一个合格的,那时候觉得HR真是神了,每次电话请过来面试的人都是服务器端的程序员。而且从招聘网站上,我也发现很多小公司会对某个职位持续地招聘2、3年,这显然是招人难的侧面表现。

如果觉得招人困难的时候就要花时间去培养了。培养简单吗?也不简单。特别是对于小公司来讲,具备软件技能培养能力的人少之又少,,而且这种人都被拉去做事了,哪有时间去培养其他人。而且软件领域里各个层面都充斥着领域专家。要一个Java程序员心甘情愿地去受一个JavaScript程序员的培训很可能就不是一样很顺利的事情。

如果公司缺少优秀的人才就去赶紧招聘,猎头很多时候是不靠谱的,我这么说可能引起了猎头们的不满,那换一种说法,猎头极少时候是靠谱的。如果没有资金和条件吸引优秀的人才,就花时间和能力去培养,如果连培养的时间和能力也不具备,那就等着杯具吧。

分类: Develop & Design 标签:

AIR2对HTML5的支持力度

2010年6月20日 ColorHook 没有评论

html5test是一个测试浏览器对HTML5支持情况的一个web应用。在github上可以看到作者公布的一些测试结果。Adobe AIR2对HTML5, CSS3都提供了增强,我记得用html5test对AIR1.5的测试结果在20分左右,今天再用它测试一个AIR2。demo代码如下:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
					   xmlns:s="library://ns.adobe.com/flex/spark" 
					   xmlns:mx="library://ns.adobe.com/flex/mx"
					   creationComplete="init()">
	<fx:Script>
		<![CDATA[
			import spark.components.Group;
			import spark.core.SpriteVisualElement;
 
			protected var htmlLoader:HTMLLoader;
			protected var htmlUI:SpriteVisualElement;
 
			private function init():void{
				htmlLoader=new HTMLLoader();
				htmlLoader.width=800;
				htmlLoader.height=this.height;
				htmlLoader.load(new URLRequest('http://html5test.com'));
				htmlUI=new SpriteVisualElement();
				htmlUI.addChild(htmlLoader);
				this.addElement(htmlUI);
			}
		]]>
	</fx:Script>
</s:WindowedApplication>

运行后发现得分依然是很低——46分,跟Android 1.6的得分42分差不多,不过跟iPhone, iPod touch的120多的得分来比真是差的很远。Adobe官方有一篇文章讲到了AIR2对HTML, CSS, JavasScript的支持情况以及不支持的个中缘由。

分类: Develop & Design 标签: , ,

使用AIR2录制音频

2010年6月20日 ColorHook 没有评论

AIR2的正式版总算是出来了,前些天SDK也放出来了,于是就鼓捣一下它的一些新特性,其中一个特性就是录制Microphone,本地录制,本地存储,不需要FMS的协助。

为了完成这个录制Microphone的功能,我们需要先做如下事情:

  1. 下载AIR2 SDK并覆盖到Flash Builder的SDK中。
  2. 下载adobe官方用于保存WAV音频的开源库WAVWriter

接下来,新建一个AIR2工程,为了力求简单,本例中只用一个按钮,用于开始录制和停止录制。UI代码大致如下:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
				xmlns:s="library://ns.adobe.com/flex/spark" 
				xmlns:mx="library://ns.adobe.com/flex/mx"
			        creationComplete="init()">
        <fx:Script>
		<![CDATA[
                ]]>
	</fx:Script>
	<s:layout>
		<s:VerticalLayout paddingTop="10" horizontalAlign="center"/>
	</s:layout>
	<s:Button id='controlBtn' label="{controlBtnLabel}" click="clickHandler()"/>
</s:WindowedApplication>

下面开始编写逻辑代码,程序启动后,初始化Microphone, 设置音频文件保存路径。

import com.adobe.audio.format.WAVWriter;
import mx.controls.Alert;
 
protected var targetFile:File;
protected var microphone:Microphone;
protected var recordedData:ByteArray;
 
private var recordFlag:Boolean=false;
private static const START_RECORD:String='start recording';
private static const STOP_RECORD:String='stop recording';
[Bindable]public var controlBtnLabel:String=START_RECORD;
 
private function init():void{
	if(!Microphone.isSupported){
		Alert.show("Cannot find a Microphone");
		controlBtn.enabled=false;
		return;
	}
	targetFile = new File(File.desktopDirectory.nativePath+"/sound.mp3");
	microphone = Microphone.getMicrophone(0);
	microphone.setSilenceLevel(0);
	microphone.rate = 44;
}

然后处理按钮的动作,执行开始录制或停止录制操作。

private function clickHandler():void{
	if(recordFlag){
		controlBtnLabel=START_RECORD;
		recordFlag=false;
		this.stopRecording();
	}else{
		controlBtnLabel=STOP_RECORD;
		recordFlag=true;
		this.startRecording();
	}
}

开始录制时,先删除原有的音频文件,然后监听Microphone的SampleDataEvent.SAMPLE_DATA事件。

public function startRecording():void{
	if(targetFile.exists){
		targetFile.deleteFile();
	}
	recordedData=new ByteArray();
	microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, onMicData);
}
 
private function onMicData(event:SampleDataEvent):void {
	recordedData.writeBytes(event.data);
}

当点击了停止录制时,移除Microphone的事件监听,并使用WAVWriter来生成一个音频文件。

public function stopRecording():void{
	microphone.removeEventListener(SampleDataEvent.SAMPLE_DATA, onMicData);
	saveWAV();
}
 
public function saveWAV():void{
	var wavWriter:WAVWriter = new WAVWriter();
	var stream:FileStream = new FileStream();
 
	recordedData.position = 0;
	wavWriter.numOfChannels = 1;
	wavWriter.sampleBitRate = 16;
	wavWriter.samplingRate = 44100;               
 
	stream.open( targetFile, FileMode.WRITE );
 
	wavWriter.processSamples( stream, recordedData, 44100, 1 );
	stream.close();
}
分类: Develop & Design 标签: ,