2014年12月16日星期二

VIM相关

这两天一直在使用VIM,相关想法如下:
  • 并不难学
  • 插件开发似乎也不是很难
  • 不打算使用第三方的插件
要做的插件:
  • 括弧匹配检查
  • 在括弧之间跳动,特别是花括弧。仅在“{”之间跳跃。
  • 在各种符号之间跳动。代码事实上是由符号和英文标识符组成,符号在代码中占有很大的一个比例,包括加减乘除、大于小于、与或非等、各种括弧、标点符号。此功能没有价值
哲学与思索

做软件开发工作其实也有一定的年头了,自觉有些感悟,但是总是有一种欲说还休的感觉。但是说道这个工作中的一些事实,总是不会变得。引用别人说过的一句“Programmers shape ideas into text.”所以文本编辑其实就是一个根本。这一点和网络作家其实有些相似,我们都是码字的。

卡顿

这个是绝对不允许的。

tag跳转

tag跳转是很必要的,特别是在阅读别人的代码的时候。改别人的程序是很通常的一件事情。当然也是一件不幸的工作。

代码补全

个人认为其实代码补全功能不是很重要。

语法检查

对于一些动态的语言,这个其实不是非常的重要。对于Java之流似乎有些用处。个人认为不一定需要这个功能。

语法高亮

这个必须得有,而且要很灵活,能够动态的高亮一些特殊需要的东西,具体想法还在形成中。

括弧检查

这个其实还是有需要的。

插件

VIM的一个很大的乐趣就是自己定制,所以不要去网上下别人的插件,尽可能的自己实现一些常用的功能。量身定制显然更高大上。而且在一个新的环境上也不会影响你的效率。















2014年11月12日星期三

算法

面向对象的解决方案和算法解决有很大的差别。从问题的理解和分析上也有所不同,我不知道哪个好,但是面向对象的方式的性能明显不是最优的。在解决实际问题上,我一向倾向于使用面向对象的方法来处理。但是显然使用面向对象的方式解决问题其性能的确是比较差的。而理解性也并非十分的好。唯一的优势在于多人分工的时候,比较容易解决分工合作的问题。

而在面对算法问题的时候,还是需要考虑性能的。尽可能的使用高性能的处理方式,不要使用JAVA的集合类。使用最最基础的数组来进行处理。或者不要使用递归,而使用循环,递归的性能很差,尤其在JAVA语言中。

2014年8月14日星期四

Joana Zimmer Luky Star

非常喜欢这首歌,旋律和歌词都很不错。不过其实英文歌的歌词是非常露骨的,非常直接。也许英文的表达就是这样,我其实不太关注英文的诗歌,因此也不太懂。这段时间决定去了解学习一下。

下面是我的翻译。不是直译了。基本上是一种意译,像这样的艺术作品,直译是不可取的。而且也基本不可能。

Can't you see you are
the one I'm always thinking of
为何你对我的思念视而不见

In my Dreams you are already mine
在我梦中,你早已和我相伴

If you show me love
I promise I'll be there for sure
若你爱我,我将矢志不渝

I would stay forever by your side
我会日夜陪伴在你身畔

Look at me now!
看着我

can't you see all the love in my eyes
难道你读不出我眼中的痴情

And will you give it a try
难道你不曾被我打动

Will you be my lucky star
你是否会是那个带给我幸运的人

Be the one to show me who you are
你是否会是那个示我以真心的人

will you guide me through the nights
你是否会是那个带我穿越黑夜的人

be my every shining light
你是否会是那个带给我永远光明的人

will you be my lucky star
你是否会是那个能带给我幸运的人

Be the one to show me who you are
你是否会是那个能示我以真心的人

cause I know this could be love
shining on my heart
因为我知道,这将会是照亮我心间的真爱

wu m
What if I would tell
exactly how I feel for you
如果我向你诉说我的一往情深

would you run
你是否会默默逃避

Would you oh would you let me down
你是否会让我忧伤失望

look at me now
看着我

Will you give this love a try
你是否会对我的爱视而不见

I got nothing to hide
我从不曾隐藏我对你的情感

Will you be my lucky star
你是否会是那个带给我幸运的人

Be the one to show me who you are
你是否会是那个示我以真心的人

will you guide me through the nights
你是否会是那个带我穿越黑夜的人

be my every shining light
你是否会是那个带给我永远光明的人

will you be my lucky star
你是否会是那个带给我幸运的人

Be the one to show me who you are
你是否会是那个示我以真心的人

cause I know this could be love
shining on my heart
因为我知道,这将会是照亮我心间的真爱

m
ho ye

Look at me now!
看着我

can't you see all the love in my eyes
难道你读不出我眼中的痴情

And will you give it a try
难道你不曾被我打动

Will you be my lucky star
你是否会是那个带给我幸运的人

Be the one to show me who you are
你是否会是那个示我以真心的人

will you guide me through the nights
你是否会是那个带我穿越黑夜的人

be my every shining light
你是否会是那个带给我永远光明的人

will you be my lucky star
你是否会是那个能带给我幸运的人
Be the one to show me who you are
你是否会是那个能示我以真心的人

cause I know this could be love
shining on my heart
因为我知道,这将会是照亮我心间的真爱

不知道这样翻译对不对,反正也找不到可以交流的人。


2014年4月29日星期二

开发与工具

今天在网上随便逛了一下,看了看一些人在osChina里面对于编程语言与技术的一些争论。让我有了一些想法。

其实我觉得编程技术的发展其实和人类社会在其他领域上技术的发展本质上来说没有大的区别。而技术的发展方向本质上来说是从效率和质量这两个方向上进化的,也就是说,新的技术总是能够带来更好的质量,或者更好的效率,不过使用起来可能会更复杂一些。而从根本上来说新技术总是依托在某种工具上来实现的。比如,现在在土木工程上面,随处可见的大大小小的工程机械,特别是挖掘机,大大小小,种类俱全。而挖掘机的工作实际上就是替代了铁锹和镐头。但是它使用起来要比铁锹和镐头要复杂很多。挖土这种工作显然,质量上很容易保证,但显而易见,挖土机的工作效率比人高多了。软件开发基本也是如此,我们和其他工业领域,没有本质上的差别。

开发技术的发展其方向大体上也基本等同于工具的发展,总是向利于高效的方向来发展的。因此我们也应该看到,技术在很大程度上不可能一成不变,发展与进步是一种必然。

软件开发一个有趣的地方在于,你所使用的语言和工具很大程度上也是一种材料,一旦你使用了某一种,就不太容易换另一种。所以现代的开发平台,大体上都允许你使用多种语言来开发,比如微软的开发平台,上面支持很多种语言。Java也是走的这个路线,Java平台上现在已经有很多的语言实现了。

人类,总是趋向于使用某种工具的。人类总是趋向于使用抽象的,易于理解的,高效的工具。开发也是一样。因此我趋向于应用规范标准的类库,而不是私有的类库。类库的维护成本是很高的,而且,我刚才简单论证过了,编程工具化的过程基本是无法避免的。无论是从组织要求上来说,还是从技术要求上来说,都是一样的。

抽象度高的代码,显然更容易让人理解,从而也容易维护。

说白了,就是因为人类本质上善于发现和认识,这也是人类的一个很基本的特征。所谓的知识往往就是人类识别出来的这些模式与认识的一种集合和积累,有的完善,有的不完善。在哲学上来说,我记得认识还有两次飞跃。从感性认识到理性认识的飞跃,从理性认识到实践的飞跃。而开发工作其实就是在第二次飞跃上工作,也就是说理论在指导实践。

总之语言的发展必然会不断的提高其抽象程度,和机器有关的细节会越来越少。另外也应该看到,这个过程不可能是一两个人或者几个公司能完成的,需要整个社会的共同努力。

2014年3月24日星期一

clojure调用javaFX

知其然,不知其所以然,大概我就是这种人。不多说直接上代码:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(ns myproject.core
  (javafx.embed.swing.JFXPanel.)
  (:import [javafx.application Application]
           [javafx.event ActionEvent EventHandler]
           [javafx.scene Scene]
           [javafx.scene.layout VBox StackPane]
           [javafx.stage Stage]
           [javafx.scene.control Button])
  (:gen-class :extends javafx.application.Application)
  )

(defn -start [this stage]
  (def pane (StackPane.))
  (def btn (Button. "xxxx"))
  (.setOnAction btn (proxy [EventHandler] [] (handle [event] (println "click" event))))
  (.. pane (getChildren) (add btn))
  (def scene (Scene. pane 300 200))
  (doto stage (.setScene scene) (.setTitle "zxxxxz") (.show))
  )
(defn -stop [app]
  (println "Exiting now"))

(Application/launch myproject.core (into-array String []))

注意命名空间里面的:(javafx.embed.swing.JFXPanel.);这句话非常重要,如果没有你会得到一个运行错误,说什么Toolkit如何如何。加上就好了。至于原因,over stack网站上似乎有解释,但是我是一个不求甚解的人,所以其实就是基于某些原因,普拉普拉普拉。

注意如果你使用的是intellij,注意配置:










2014年2月27日星期四

Angular 组件

在angular里面,指令其实和组件的意思是完全不同的,但是多数人并没有很好的区分它们。并把指令提升到了完全和组件相当的高度去了,这大大加剧了指令的编写难度。事实是指令和组件完全是两个概念。

Angular的核心思想应该是以数据为中心的,但是方法是否应该是数据的一部分,这个问题还是值得商榷的。就算从比较纯的函数观点来看的话,完全无副作用的函数似乎也不应个视为与数据等同。Angular解决方法与数据间隔阂的方法其实就是通过事件完成的,说的更直白一点其实就是scope中的$watch方法。这个方法让我们得知了数据的变化,可用从容的对数据进行处理,并把视角从处理数据的方法上转回到数据本身上来。

但是如果从数据的视角(也就是angular的视角)来看的话,组件就十分的复杂。因为组件会牵扯复杂的DOM变化,和相应的数据变化,这些数据变化可能十分的剧烈,而似乎这些数据的变化也可能并不需要知会angular所感知的数据模型部分(也就是scope)。因为组件从来都不是以数据为中心的,恰恰相反,组件往往就是来操作数据的,比如说增查删改。数据在组件这里往往都是从属的对象无法被视为中心枢纽。所以组件的视角和angular的视角总是矛盾的。这也是往往在使用指令来卡法组件时让我们感到不利索的原因。此外,指令的嵌套也会使数据模型之间的关系变得复杂。因为指令往往也会有一个scope以及和它相关的作用域。这些原因导致使用指令的组件不但设计实现困难,且使用起来也很不方便。归根结底就是因为指令并不是实现组件的好方式,特别是复杂的组件。

个人认为,一个比较好的做法是把页面的组件干脆封装成独立的JS对象,把对scope的数据操作彻底的封装成相应的事件。这样似乎能够好一点。这个对象自己决定在何时传递数据。

不过我一向不认为纯粹的就好,恰恰相反,我认为简单,直接,有效的才是好的。繁复的做法一定要有原因,如果仅仅是为了契合某种说不清道不明的哲学,我认为是完全不值得的。最后审视一下我们的项目,我觉得require js的作用远远大于angular js。事实上,我倒觉得,angular并不是一个好的系统框架,而是应该作为某个前台系统框架的一部分,这样应该是比较好的。不过这个系统得多复杂呀。我的经验告诉我,复杂的设计注定不能长久。

2014年2月25日星期二

过渡设计

过渡设计其实是一个很有趣的主题,因为设计是一种人为的主观行为,并不太容易受到制约。而且设计也很难界定,大体上当你打开你的开发工具,并在键盘上敲下第一个字母的时候,设计的内容已经开始在你的头脑中展开了。但其实在软件领域里面,提到的设计大约都是指的架构设计,架构设计是没有什么所谓过渡设计这么一说的,因为架构设计和业务场景关联的十分紧密(适用一切的架构是不存在的),否则就是失败的,而且这一点也十分的容易发现,并不需要软件方面的专家。

而我们所说的过渡设计其实存在于实现的设计中。是的,实现的设计,这个设计在软件工程中似乎并没有太大的地位,但也并非不被重视。主要是这个阶段的设计比较难做,同时也很难管理和控制。个人觉得,在多数的公司中,都没有明确的提出实现设计,并将其列为软件质量的一个重要指标。

但其实实现设计中的过度设计也并不难发现,首先要明确一点,不能因为可能过度设计就不去设计了。并从而否定面向对象思想或者面向方面的开发方式。毕竟我们总是需要一种可以思考的方式并且需要能够和别人沟通和交流。因为实现的过程不可能是孤立的,任何软件都几乎不可能一个人完成。除非你是特殊材料制成的,我们一般管这种人叫天才。不过这种人太少见了,不必考虑他们对于实现的影响。

首先,设计是为了应对变化。也就是说,我们通过各种手段去进行所谓的设计,其目的就是为了让我们的代码有潜在的被改动或者被扩展的这种可能性。比如我们引入了某个接口,这样我们就有了替换实现的可能性。接口在设计中其实就是为了隔离实现的。另外我也可以使用多态性通过改变子类的行为的方式来扩展我们的业务。没有人可以保证业务是永远不变化的,其实业务或者业务的实现方式或多或少都会随着时间而改变,而且时间越长,这种变化就可能会越剧烈。因此支持变化往往是很有必要的。

其二,设计总是为了更好的和业务契合,也就是固化某些核心的逻辑。换一种说法就是在创造某一种DSL语言,这让我想起了格林斯潘第十定律。这也是非常重要的,核心业务往往就是某种产品或者某家公司赖以生存的根本。因此通过一些手段固化这些业务是十分重要的。而且核心业务往往很久都不会发生变化。比如QQ的聊天功能,office的编辑功能,游戏的价值观等。所以设计总是需要为业务来提供便利,越复杂的业务,这个需要就越发的明显。

第三,设计是为了更容易的扩大开发的规模。通过适当的抽象和合理的封装以及分层,把系统的核心和外延分离,以便于能够通过增加人手来提高开发的效率,同时也要避免初级程序员的破坏性。这也是为什么很多的系统喜欢使用spring来开发的原因。使用spring的系统从这个意义上来说,应该不是非常重要的系统。

最后,设计往往应该能够更好的支持测试。开发者往往都不怎么喜欢测试,一般来说他可能更相信自己的直觉。当然,直觉有的时候准确的可怕,但有的时候却错的离谱。所以用多种手段来保证开发的正确性是十分必要的。而测试往往具有很多的层次,对于实现的设计来说,测试更多的指的是单元测试。为了能过更好的支持单元测试,往往需要在设计上进行一些让步。越核心的功能,单元测试就越重要。特别是类库的设计,必须要考虑各种各样的情况,如果没有单元测试,根本无法保证类库的健壮性。

除此之外的设计大多数都是过渡的设计,比如我们为何使用依赖注入技术?因为我们有很多的依赖关系需要管理,而且在不同的层次上希望能够降低耦合性。IOC并不会带来代码阅读或者维护上的便利,因此如果你的系统是一个层次分明,功能确定的系统,IOC其实就是一种过渡设计。所以我发现大多数应用了spring框架的系统往往都是过度设计了的。因为其实你的系统完全不需要那种千篇一律的层次划分和解耦方式。

过渡设计还有一个有趣的特征,那就是一旦有了过渡的设计,为了让这个设计看起来合情合理,那么往后的设计就会有越来越过渡的趋势,直到被废弃。这时你会发现所谓框架的代码量比你业务的代码量要大得多。我把这种情况称为过度设计漩涡,一旦卷入,就无法脱身,并且随着代码的增加,设计的填补,设计会越来越过渡。

使用springhibernate这样的框架来解决问题,似乎已经成了java开发的一种趋势。但其实这些框架掌握起来并不容易,而且一旦使用,往往都会陷入过渡设计的漩涡。严重影响系统的可读性和运行性能。而且你一旦学会了spring或者hibernate的思考方式就更为的可怕,因为他们总是把问题搞的很复杂。复杂的框架以及其运作的方式会把你的业务搞得杂乱无比,你甚至可能还需要去学习一种框架专用的DSL。我觉得这种行为其实就是舍本逐末。