上周讲了A* 的基本原理, 不知道有人能看懂不? 其实原理并不是非常复杂, 但实现起来的方案倒是有不少, 就像所有算法一样, 一般来说, 实现都比原理难得多.不过篇幅有限, 这里就不谈实现了, 只谈原理.

寻路算法介绍完了之后, 就来讲讲如何生成数据, 就和人的双腿一样, 数据就是寻路模块的另一条腿.

这里我尽量简单的 用我自己的表达方式来描述, 由于过程很多, 我也没有能非常好的理解, 所以有遗漏还请大家补充.

我们的网格生成主要是用了这个方法Navmesh, 原理介绍我主要参考了这个网站, 有兴趣的同学也可以了解一下: http://www.critterai.org/nmgen_study

navmesh的生成主要有这么几步:

  1. Voxelization – Create a solid heightfield from the source geometry.
  2. Generate Regions – Detect the top surface area of the solid heightfield and divide it up into regions of contiguous spans.
  3. Generate Contours – Detect the contours of the regions and form them into simple polygons.
  4. Generate Polygon Mesh – Sub-divide the contours into convex polygons.
  5. Generate Detailed Mesh – Triangulate the polygon mesh and add height detail.

体素化Voxelization

这一步是向量空间(vector space) 到 体素空间(voxel space) 的转换. 用到的是叫保守体素化(Conservative voxelization) 的算法, 它保证了每个多边形面都能完全被生成的三维象素(voxel)包裹, 如下图:

体素化后, 生成的都是可寻路的高度场(heightfield)信息, 不可寻路部分被剔除.这一步是从一个固态高度场(solid heightfield) 生成一个开放高度场(open heightfield) 的过程, 一个开放高度场表示在一个固态空间上可能寻路的平面.

这个概念有点抽象, 请往下看…

区域生成Region Generation

这一步的目标是进一步的定义,那部分的面是可以寻路的, 并且把寻路区域分隔成连续的平面以供最后生成简单寻路多边形.

最终结果如下图, 墙体,围栏, 柱子, 桌子底等不可能寻路的平面在这步根据邻居信息和分水岭算法(the watershed algorithm) 被剔除, 一些孤立的小局域(比如桌子表面) 也被剔除.

留意楼梯, 虽然是多级, 个平面并没有连通, 但是也会被当做一个平面(绿色). 楼梯扶手等平面也被剔除.

轮廓生成Contour Generation

这一步将完成从体素空间回归到向量空间的转换. 区域(region) 的轮廓将被"遍历(walk)", 形成简单的多边形.

其中, 有些区域被合并, 多边形的边更平滑, 边长度被优化.

这一步结束后, 可寻路区域已经被一些简化的多边形所表示

凸多边形生成Convex Polygon Generation

凸多边形生成算法很多,这里就不多介绍, 这里主要是使用了把多边形切分为三角形, 然后尽量合并的方式做, 结果如下图:

精细网格生成Detailed Mesh Generation

这是navmesh的最后一步, 凸多边形通过"德劳内三角化"(Delaunay triangulation) 算法三角化成包含高度信息的三角形(注意楼梯)

顶点信息也会在这里补到各个三角形上, 以保证高度信息和模型保持一致.

至此, 寻路的数据生成完毕, 可以用于简单寻路系统. 各部分数据都有可能被寻路算法使用, 有多种方法去获取到数据以用于决定寻路的各个步骤.

其实上面的每一步都可以展开很多, 整个navmesh的生成非常复杂, 而且用到了许多算法, 完全可以写几篇论文以介绍, 这里就不展开了(我也没这实力),

有兴趣深入的同学可以参考下面的几个网站, 里面都非常专业的提供了实现方面的介绍(包括实现):

http://digestingduck.blogspot.com/2010/05/constrained-movement-along-navmesh-pt-2.html

http://code.google.com/p/recastnavigation/

 

上次说到,寻路算法主要是使用A* 算法,而算法的简单流程也已经介绍过,这里贴一下更具体一点的算法内容。

A*(A-Star)算法是一种静态路网中求解最短路最有效的方法。

公式表示为: f(n)=g(n)+h(n),
其中f(n) 是节点n从初始点到目标点的估价函数,
g(n) 是在状态空间中从初始节点到n节点的实际代价,
h(n)是从n到目标节点最佳路径的估计代价。

保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:

  • 估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。
  • 如果 估价值>实际值, 搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。
  • 估价值与实际值越接近,估价函数取得就越好。
  • 例如对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy- ny)*(dy-ny));这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。明显优于Dijstra算法的毫无无方向的向四周搜索。

主要搜索过程:

  • 创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
  • 遍历当前节点的各个节点,将n节点放入CLOSE中,取n节点的子节点X,->算X的估价值->
  • While(OPEN!=NULL)
    {
    从OPEN表中取估价值f最小的节点n;
    if(n节点==目标节点) break;
    else
    {
    if(X in OPEN) 比较两个X的估价值f //注意是同一个节点的两个不同路径的估价值
    if( X的估价值小于OPEN表的估价值 )
    更新OPEN表中的估价值; //取最小路径的估价值
    if(X in CLOSE) 比较两个X的估价值 //注意是同一个节点的两个不同路径的估价值
    if( X的估价值小于CLOSE表的估价值 )
    更新CLOSE表中的估价值; 把X节点放入OPEN //取最小路径的估价值
    if(X not in both)
    求X的估价值;
    并将X插入OPEN表中; //还没有排序
    }
    将n节点插入CLOSE表中;
    按照估价值将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
    }

Image.jpg

上图是和上面Dijkstra算法使用同一个路网,相同的起点终点,用A*算法的情况,计算的点数从起始点逐渐向目标点方向扩展,计算的节点数量明显比Dijkstra少得多,效率很高,且能得到最优解。

 

上周对寻路做了一些原理和API上的了解, 由于寻路算法实在是博大精深,涉及很多知识,一周时间太短,理解尚浅,就以我现在了解到的归纳一下,如有理解不对的地方,欢迎跟帖指正~

寻路算法属于人工智能的范畴,分静态和动态两种,动态的太高端,暂时没有了解,静态的话也有好几种,Dijkstra,A*和D*等。在网上搜寻了一下,3d 游戏的寻路算法主要还是A* (a-star,A星)使用的比较广泛,它有快速、路径短,不成环等优点,在orge,unity等引擎中得到了广泛的使用。

A*的最初设计是基于2d平面,对于3d 寻路就需要先对场景进行处理, 我们游戏貌似一般叫它navmesh,简而言之就是把场景网格化,生成一个可寻路的平面,把3d的问题转化为2d的问题,然后就可以通过A*进行寻路。

所以3d 游戏寻路大致分为2部分:

  1. navmesh
  2. A*

navmesh比A* 要复杂很多,而由于A*可以在2d平面进行,理解起来会更简单一些,所以这里先简单介绍一下A*的原理。

先做一下术语的说明:

  • 开启/关闭列表:算法的过程变量。可简单理解为临时记录区
  • G值:从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。
  • H值:从网格上那个方格移动到终点B的预估移动耗费。
  • F值:G + H
  • 父节点:记录最短路径用

下面是算法过程(可直接导成伪代码):

1,把起始格添加到开启列表。
2,重复如下的工作:
a) 寻找开启列表中F值最低的格子。我们称它为当前格。
b) 把它切换到关闭列表。
c) 对相邻的8格中的每一个?
* 如果它不可通过或者已经在关闭列表中,略过它。反之如下。
* 如果它不在开启列表中,把它添加进去。把当前格作为这一格的父节点。记录这一格的F,G,和H值。
* 如果它已经在开启列表中,用G值为参考检查新的路径是否更好。更低的G值意味着更好的路径。如果是这样,就把这一格的父节点改成当前格,并且重新计算这一格的G和F值。如果你保持你的开启列表按F值排序,改变之后你可能需要重新对开启列表排序。

d) 停止,当你
* 把目标格添加进了关闭列表这时候路径被找到,或者
* 没有找到目标格,开启列表已经空了。这时候,路径不存在。
3.保存路径。从目标格开始,沿着每一格的父节点移动直到回到起始格。这就是你的路径。

原理不是非常复杂,但是看上去有点抽象,更详细的下周继续,敬请留意。

 

一直觉得“理财”这个词很高端, 也总想自己可以高端,于是就总想理理。虽然财很少,但据说理理可以有变化,变多变少不一定,但改变才是永恒。

又据说记账是理财的第一步,还必不可少,于是尝试找一些软件来协助一下。

碰巧周末又看见一微博,让我觉得还有教育下一代的必要,自己不懂就更说不过去:

【洛克菲勒家族的零花钱教育】洛克菲特家族的孩子每周都能领到三角钱零花钱,但必须分成三份:自己花、储蓄、施舍。孩子们每一分钱的用途和时间都必须记录在小账本上,周末进行检查。如果谁漏记了一笔帐,罚五分钱;而记录无误的则可得到五分钱的奖励,以此培养孩子勤劳节俭的美德和艰苦自立的品格。

简单理了下,我的记账需求大致如下:

  • 方便,可以随时随地
  • 有明细
  • 可输出报表
  • 跨平台
  • UI 能用(中文版软件,要求“好用”貌似有点过分。。。)

由于第一点,所以基本目标锁定了手机软件。芸芸android市场中,看见一个是由金蝶开发的,叫”随手记“,虽然从来没用过金蝶,但知道ERP,知道好多财务都是用它,大厂,名气大,我看行。于是就下载了来试试。

几番把玩,发现有几个优点:

  • 软件不算很大,apk大概4M多,启动比较快。
  • 记账方便,分类较细,属性有金额,帐户,商家。。。这点很关键,我不希望花费太多时间在”记"这个动作上,我更希望把时间放在月终的数据整理上。
  • 跨平台同步。这个功能也很关键,特别是现在大家每天都在各种设备上不停的切换迁移,不跨平台太痛苦。没Mac是一缺陷,但可用web版补救,也算方便。
  • 可输出各种报表。通过各种属性进行筛选,分类,比较清晰,不愧是做ERP出身,这点小case 还是too simple。
  • UI 做得还不错,主界面分类较清晰
  • 还可以为账目添加照片

总体感觉这个软件还不错,免费版基本能满足需求。VIP 版也就20RMB, 也在合理范围之内,可以接受。

不过有几个功能一直很希望能有一款软件支持,可惜没有。。。顺便吐槽一下:

  • 根据信用卡消费明细自动记账。招行专业版有这个功能,但太独立了,总不能我两个地方分开记吧?这点很不给力。
  • 和B2c, C2C?的电商整合。现在好多金钱都是在taobao,京东,当当这样的电商网站上消费走的,如果能导出上面的数据自动分类记账,那就很赞!

在这个高聚合的互联网时代,能出一个这样的产品,市场应该还是不小的,至少我自己是很看好这样的应用,可惜自己没这个时间和精力去做。。。 哪位如果开发了,记得通知我,只要保密和隐私能保护的好,我一定属死忠用户!

最后补充一些界面的介绍(点击看大图):
记账界面,看见那个摄像头的图标没有?那就是为这条流水附加的照片入口:
豌豆荚截屏(0)

这是进入的主界面,可以看到汇总数据:
豌豆荚截屏

可以设置各种帐户:
豌豆荚截屏(1)

分类汇总,类别很细,很清晰:
豌豆荚截屏(2)

这是预算的分类,具体可以定制: 
豌豆荚截屏(3)

备份功能也很强大,直接搞到sd卡上,可以存到自己的电脑中。
豌豆荚截屏(4)

 

原文: http://h30565.www3.hp.com/t5/Feature-Articles/Linus-Torvalds-s-Lessons-on-Software-Development-Management/ba-p/440

如果让我选 "谁是世界上最天才的软件项目经理", 我会认为Linus 当之无愧. Linux 内核, 一个集千万程序员智慧的结晶, 现在已经给广泛用于各种设备, 而发起者和项目最高管理者一直没有变过, 都是Linus Torvalds.

在linux 之前, 开源项目几乎从来没有如此强烈的影响力, 而如何聚拢全球开发者, 有条不紊的开发一个成功的产品, 曾经被认为是mission impossible, 但Linus 做到了.

查了下linux kernel的发布流程, 大致如下:

2.6.x 内核树
2.6.x 内核树是有Linus Torvalds维护的,可以在kernel.org的pub/linux/kernel/v2.6目录里找到。它的开发流程是这样的:
- 当一个新的内核发布之后,一个为期两个星期的窗口打开,在这段时间里维护者可以提交大的补丁给Linus,通常是已经在-mm内核中存在了一定时间的补丁。推荐的提交补丁的方式是通过git(有关git的更多信息可以在http://git.or.cz/找到),但是普通的补丁也是可以的
-两个星期之后一个-rc1内核发布,然后现在只可以再加入不会为内核添加新功能的补丁,因为那样的补丁可能会影响这个内核的稳定性。请注意这个时候一个整的新驱动(或者文件系统)可以被接受。因为只要这个变动是自成一体的并且不影响它之外的代码的话,就不会有产生回归的危险。在-rc1发布之后,git可以用来发送补丁给Linus,但是这些补丁也需要发到一个公开的邮件列表里以备审查。
- 当Linus确信当前的git(内核代码管理工具)树已经处于一个合理的健全状态,足够测试时,一个新的-rc就会发布了。目标是每周发布一个新的-rc内核。
- 这个过程将会持续到内核被认为可以发布为止,整个流程会持续大概6个星期。
Andrew Morton在linux-kernel邮件列表里写的有关内核发布的一句话值得提一下: “没有人知道什么时候一个内核会发布,因为它发布的依据已经掌握的bug状态,而不是事先设想好的一个时间线。

可以看到, Linux 的内核发布是很神奇的一个存在! 最终节点只有一个: Linus!

记得有一次linux 2.6 有一个严重的bug, 导致部分显卡无法正常工作, 但是没法做hotfix, 原因是: Linus 去美国度假了…

Linus 是一个传奇, 就像 Steve Jobs 一样, 是一个无法复制的神一般的存在…

well, 仰慕到此为止, 看看这次他老人家又说了什么.

  • 对于开源项目, 他的意见是: You make it public, and then you assume that you’ll have to do all the work, and ask people to come up with suggestions of what you should do, not what they should do. 为何大多数开源项目最终都是失败, 也许就是因为出发点没有找对. 忘记那个哲学家说过: 人本自私. 这也是西方普世价值之一, 不要一开始就奢望项目一放出来就会有很多人热心的加入, idea 再好, 没实实在在的东西, 没人会想着投入的.
  • 对于有人觉得代码很重要, Linus认为: “No, even if you wrote 100% of the code, and even if you are the best programmer in the world and will never need any help with the project at all, the thing that really matters is the users of the code. The code itself is unimportant; the project is only as useful as people actually find it.” 他还提到, 很多公司对代码质量很关注, 我经历过华为当时那种几乎苛刻的对代码风格的追求, 所以深有感触. Linus 认为对代码的追求胜过对用户体验的追求这个想法本身就是错误的. 他举的例子也很有代表性: 如果一个bug的fix 会影响到用户体验, 那么你就已经破坏了这个规矩. 他认为很多公司都自以为是的在破坏用户体验, 为得就是fix 一个bug.
  • 对于开发工具, Linus觉得工具并不是必须的. if you only have a few hundred patches per release, you can maintain those just about any way you want, including entirely by hand. (一个release几百个patch, 他都觉得可以by hand… 这是一种什么样的DIY 精神啊!!= =)
  • 对于版本管理, Linus的一个想法比较体现他的性格: I personally tend to think tar-balls and patches are actually preferable to that – if only because they make all developers ‘equal,’ and you don’t get the kind of model where certain people have ‘commit access,’ and the rest are second-class citizens. 这个众生平等的观念也放到了他设计的git 上. git 完全没有类似svn/cvs 的那种对读写限制的权限管理模块, 如果要做, 就是通过linux本身的权限系统来管理, git不做这种dirty work.

总体来说Linus 是IT界比较出名的愤青, 同样的Jobs 也是出了名的苛刻. 也许伟大的人总是有那么点和常人不同的地方

有兴趣的同学还可以回顾一下Linus 大神当年对C++的狂喷: http://blog.csdn.net/turingbook/article/details/1775488 我觉得还是骂得挺对的, 我也曾经对C++热衷过, 还做过一个template嵌套的项目, 但那种痛不欲生的感觉让我再也不想再深入这苦逼语言之中去, 从此也走上了anti-cpper 的这条不归路…

 

go lang, google重金召集的几个牛人自主开发的语言, 如Thompson, Unix和Plan9作者; Pike, UTF-8 字元编码作者; Robert Griesemer, 曾协助制作Java的HotSpot编译器,和Chrome浏览器的JavaScript引擎V8; 还有gcc作者等. 一帮重量级人物能做出来一个什么样的语言呢? 好奇的去体验了一下.

基础语法比较符合C的习惯, 记录点自己觉得特别的地方:

  • 很少的语法关键字. 我认为这点很重要, 一个语言设计的好坏, 我个人认为从这点就可以看到一个端倪. 怎样用更少更简洁的关键字去清晰的表达逻辑, 需要的看设计者的功力. 所以我看一个语言的时候, 一开始都会去数一下它一共有多少个关键字以判断这个语言是否容易学习. go的语法关键字是比较少的, 共25个, 作为一个编译型语言来说, 应该算是比较容易学习的了. 而lua 是20个, python是35个.而那个变态且无耻的C++是80个(不完全统计)! 大学教材真是害人, 我现在都不知道当初是怎么学的C++…
  • goroutine, 这个基本上是go 最大的亮点. 学习不深, 基本上我是理解为和lua coroutine类似的东西, 但从语言层面对这个特性有支持的语言不多, 也是因为这个特性, 让go的程序编写变得很不一样. 需要时间去调整习惯.
  • “非面向对象”. 曾几何时, OO的概念深入民心, 但最近几年, OOP 开始走下坡, 以erlang, lisp等为代表的FP的兴起, 让更多的人反省OO 是否适合程序开发. Go 也基本上改变了python或者说C++的那套模仿smalltalk的oo方式, 改成类似Objective-C 的那种消息机制(曾经写过一篇周记谈Objective-C的OO, 我认为这种机制更加符合OO的本质). Go 的描述中, 数据不再和逻辑绑定, 一个type可以在任何地方添加”方法”, 而这个type 也只是叫做”receiver” 而不是对象, 而且Go 完全抛弃了class 这个关键字, 意味着也不会有instance的这个我们耳熟能详的概念. 传统意义上为了所谓的”封装”而存在的关键字 public private等也被舍弃.
  • 代码可以没有”;”. 这点有点像脚本语言, 但编译器会在代码生成过程中把这个;补上. 作者不建议程序员使用”;”, 因为会把代码看上去的不那么的简洁. 除非一些非用不可的地方, 如for.
  • “{” 必须在一行的结尾. 这点的原因据说同上, 为的是让代码更好看. 不过过分的是, 如果不写在行尾, 编译器就报错了…
  • 没有了while, do. 取而代之的是for的单独用法: for true{ }.
  • 更强大的switch. switch是我个人比较喜欢的C 语言关键字, 它可以把一些工作变得简单(至少我可以少写好多个if else了…). go的switch 支持int 以外的所有类型, 而且有开关, 如 switch a;False{} 那么这个switch 就不会被执行.
  • 支持指针. 如果作为一个脚本语言去理解, 那么它很强大; 但作为一个编译型的语言来说, 它貌似又不那么nb, 但是在写go的时候, 往往会忘记了它原来是一个编译型语言…
    • gofmt 很好很强大. 许多语言都需要为代码风格发愁, 项目中不同的人会写出不同风格的代码, 有的项目使用Xlint 来保证代码风格, go则原生提供了gofmt 用于重新排版成prettty 的代码. 使用起来非常方便, 效果也很好.
    • godoc 简单的文档输出. 没有doxygen 的语法, godoc 提供的是最简单的文档输出, 包括系统库文档都是通过这样的方式输出的
    • 完美支持unicode. 可以这样用…
      for pos, char := range "中国人" {
      fmt.Printf("character %c starts at byte position %d\n", char, pos)
      }

    prints

    character 中 starts at byte position 0
    character 国 starts at byte position 3
    character 人 starts at byte position 6

     

    而对go的效率, 有人做过测试. 和C还是有不小的距离. 普遍c语言速度在go的2倍以上, 在一些测试(regex 实现) C领先30倍. 让不少人担心Go的性能是否能够支撑住系统级应用.

    而和python3 相比, go最多领先了165倍. 编译型的优势还是表现了出来. 但是能否在线更新这个问题还没有深入去了解.

    另外, 对于不少人关心的go和C 对接的问题, go 已经支持直接在代码中嵌入C 代码, 免去了在不同文件中切换的烦恼. 从初步的感觉上来看, 这个对接的功能很强大, 但能否满足所有的调用需求还需要深入了解才能给答案.

    总体来说, Go 的goroutine 和channel 让并发程序的开发变得更加简单, 从语言的级别对并发进行设计的语言不多, 函数式的erlang 算一个, 但它函数式的编程风格需要较长的时间适应, Go过程式语言的学习曲线要更加平顺一些. 现在还有一些问题, 比如社区中有人反应go 处理web 请求的速度不如node.js, 社区太小支持不及时等. 要说的是node.js是专业做web server的, 如果go 一出来就把行业最快的比下去了, 那做node.js的哥们估计也大郁闷了. 短短2年中, go有现在这样的成绩已经不易, 库函数也足够丰富, 只是在性能的优化上还有一些路要走, 而一帮大拿坐镇, 加上有google这样的一个强大的背后支持, 相信Go 还是会很有前途的!

 

redmine是用ruby on rails 写的, 由于有时候需要修改它的源码, 所以这周空余时间对ror 做了一点点的了解, 随意帖一下…

Ruby,一种为简单快捷的面向对象编程(面向对象程序设计)而创的脚本语言,在20世纪90年代由日本人松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)开发,遵守GPL协议和Ruby License。它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada 以及 Lisp 语言。由 Ruby 语言本身还发展出了JRuby(Java 平台)、IronRuby(.NET 平台)等其他平台的 Ruby 语言替代品。Ruby的作者于1993年2月24日开始编写Ruby,直至1995年12月才正式公开发布于fj(新闻组)。因为Perl发音与6月诞生 石pearl(珍珠)相同,因此Ruby以7月诞生石ruby(红宝石)命名。

ruby的语法不是非常复杂, 而且有点点lisp的味道, 比如调用不需要括号, 最后一次调用默认作为返回等. 但是有些语法又比较特别, 我还不是掌握的很好, 比如这样的一个语法:

respond_to do |format|

format.html

end

就有点让我莫名其妙

rails 是ruby 上的一个开源的web框架, 也是目前为止唯一的一个. 在java 基本上垄断了企业级应用的情况下, ror的 应用有些许抬头的迹象, twitter 最早就曾经用过ruby 2.0的版本, 但是由于性能问题最终还是放弃了, 换成了java.

简单接触后, 感觉rails 最大的一个特点是开发非常快速,

装好ror 之后只要简单几步, 就可以完整的建立起一个可用的网站. 如下:

$ cd ~/rails_project
$ rails demo_app
$ cd demo_app
$ script/server

然后访问主机的3000端口就可以访问

扩展也很简单, rails中有script/generate 这个脚本, 其中包括一些简单的框架生成器, 还可以从网上下载各种新的生成器, 基本上一步即可建立一个使用ajax的web 2.0 博客.

为何rails 能够快速开发, 快速部署, 主要是因为它提供了,也仅仅提供了一种开发模式, 也是我一直很稀饭的: MVC 模式.

帖个图:

这个图画的也很清楚了,就不解释了.

因此在修改应用的时候, 基本上只要换V 就可以支持不同的表现, 换C 就可以适应不同的应用.

基本上我觉得更多的时候 no choice is good choice! 像java那种, 有很多的框架也不一定是件好事. 就像mac 上的开发一样, 没有选择, 逼着你用mvc 也不一定是一件坏事

 

最近苹果IPhone/IPad 的开发火热非常, 当然, 也可以说最近移动平台的开发都很火热. 于是在空余的时间, 大概了解了一下IPhone SDK 以及上面App的开发.

大致了解了一下皮毛之后, 我对苹果的敬仰又加深几分. 有这么几点很值得学习:

  1. 完善的文档. IPhone 的SDK 非常庞大, 不亚于Win32 的SDK, 但是它的文档非常全面, .h 文件也写的非常详细. 作为一个经历了这么长时间磨练的产品, 文档的完整性绝对是给它的成功奠定了坚实的基础.
  2. 从架构上严格保证MVC 模式的应用. 众所周知, MVC 模式是UI 开发非常重要的一个设计模式, 无论在哪个写界面的SDK 都会使用这个模式, 但Apple 做的非常的严格, 如果不使用MVC 模式, 我几乎无法开发. 虽然引入模式总是会比直接操作更复杂, 不直观(没什么比hack代码更简单轻松的了… ), 但就是因为这种严格的限制, 保证了这个平台上的代码更容易维护, 更容易扩展.
  3. 编辑器无比强大. 相信大家都用过Vs, 新版本中它也非常强大, 但和苹果的Xcode相比, 它真的只是刚上路! (linux上的各种蹩脚编辑器就更是不入流了…) 强大的UI 编辑界面, 快捷智能的自动补全, 模板的生成, 帮助文档的关联…. 一个好的编辑器, 对于程序员来说, 至少可以提高30% 的效率
  4. 统一的样式设计. 在IPhone 上, 已经为各种应用设计好了统一的行为, 比如"书签", "列表", "图片" 等, 包括控件"进入""退出"的动画, 所有这些都早已经在SDK 中写好, 开发者所需要的只是把它们拉出来, 和Contorller 关联上, 设置好Model, 就基本上可以工作, 就和堆积木一样简单. 就因为这种统一, 只要这个应用中用到系统控件, 就和其他的App没有任何差别. 这也是为何IPhone上的软件, 操作习惯上都惊人一致的原因.

从上面几点可以看到, 苹果的SDK 并不是毫无限制的让开发者去发挥的, 某些自由度是被系统收回. 某些sdk 只会把一些涉及到安全问题的功能留给系统, 但苹果甚至把操作习惯都作了限制. 从开放的角度, 这也许是一个很不好的practice, 但是, 从最终的产品来看, 这个设定的效果非常的好. android的应用也是五花八门, 但为何无论如何都还是不如Apple上的舒服? 因为它们无法统一. 每个设备都是厂商定制的, 每个App 也是开发者定制的, 于是在不同的设备上, 甚至同一个App 都会产生不一样的用户体验. 而对于这种电子消费品来说, 用户体验比功能更加重要, 我认为.

  • 建议做UI 做客户端的同学也去了解, 体验一下Apple 的开发, 我认为绝对会有不少收获.
 

"Get things done" 这玩意几年前就听过, 当时一个新出的web 应用叫remember the milk, 在国外很火, 也上去玩过一下, 还和自己的twitter 和gmail 绑定了, 但找不到门道, 以为和那种传统的时间管理的是一样的, 感觉可操作性很差, 慢慢也就荒废了

最近手头上的事务很多, 比较杂乱, 压力有点大, 正好机缘巧合, 又遇到这个名词, 于是就找了一些资料了解了一下. 感觉用起来还是很靠谱的.

曾经参加过几次培训, 讲时间管理, 都是需要先计划好各个任务的时间, 分配各种优先级, 然后按照优先级排序…. 过程繁琐, 对于我这种天资不好的人, 基本上很难操作, 所以培训归培训, 回来依然没能用起来. 但GTD 比较简单, 虽然出了好多书讨论它(多数是英文), 而以我肤浅的理解是这样的: 把所有事务, 无论大小, 任意时候想到自己要做的事情, 都放到一个所谓的"bucket"中(也有叫inbox的), 然后隔一段时间清理一次这个bucket. 根据2分钟原则, 分类到next, project, waiting, someday 这4个不同的list中, 定好大致的时间. 然后每天只要看今天所对应的哪些任务, 去做就可以了. 确实在使用的过程中缓解了一点压力.

"GTD的核心理念在于只有将你心中所想的所有的事情都写下来并且安排好下一步的计划,你才能够心无挂念,全力以赴地做好目前的工作,提高效率。而当你总是有些事萦绕在心头,悬而未决的时候,你要么就是会不时地想起它而影响现在的工作,要么就是会忘记了去做。"

所以引申出来一个道理: 人的压力总是来自于自己无法控制的东西. 比如房子为何有压力? 因为房价没法控制, 不知道会升还是跌; 谈恋爱为何有压力? 因为对象无法控制, 不知道会不会某天离你而去; 等等; 而当各种事务在自己的控制范围(至少看上去在你的控制范围) 内的时候, 人的压力就会变小, 可以更专注于眼前的工作.

GTD提出者是建议用笔和笔记本, 随时记录, 而现在整个过程现在有软件可以协助, iphone上也有好几种, 如Next!, Wunderlist, RTM等, 有兴趣的同学可以一试. 理解不深, 希望和有兴趣的同学多交流.

下面转了一点资料, 供参考.


GTD的由来

GTD在Amazon的销售排名中名列98位,在国外的Blogger中也引起大量的讨论与研究,而《尽管去做》这本书在国内却没有引起太多的反响,而且国内大部分对于GTD的讨论都集中在几个主要的PDA论坛,中文Blog圈中的相关讨论则很少,而且其中还有不少是转摘的内容。《 Getting Things Done-The Art of Stress-Free Productivity》一书的作者David Allen将GTD总结成为一种将繁重超负荷的工作生活方式变成无压力高效的 时间管理系统。

GTD的主要原则

总述

主要原则在于一个人需要通过记录的方式把头脑中的各种任务移出来,通过这样的方式,头脑可以不用塞满各种需要完成的事情,而集中精力在正在完成的事情,是一种消灭压力的高效工作方法。

搜集

把任何你需要跟踪或者记住或者做的事情记在Allen称之为‘水桶’的地方:一个收件箱,电子邮箱,磁带, 笔记本,PDA,或者它们的组合。把你脑子里的任何东西都拿出来放到你的搜集设备里,准备好做下一步的处理。每星期所有的水桶都应该被至少清空一次。

处理

处理你的收件箱要遵循一个严格的工作流程
从最上面开始
一次处理一项
不把任何东西放回收件箱
如果任何一项需要做:
做(如果花的时间少于两分钟)
委托别人完成
或者把它延期
否则
把它存档以便查询,
把它扔掉,
或者使它成熟以便下一步的处理
两分钟原则:任何事情如果花的时间少于两分钟,那么马上就去做。两分钟是一个分水岭,这样的时间和正式地推迟一个动作所花的时间差不多。

组织

Allen描述了一个建议的列表集合,你可以用来跟踪需要关注的项目:
下一步行动(Next actions) – 对于每个需要你关注的事项,定好什么是你可以实际采取的下一步行动。例如,如果事项为“写项目报告”,下一步行动可能 会是“给Fred发邮件开个简短会议”,或者“给Jim打电话问报告的要求”,或者类似的事情。虽然要完成这个事项,可能会 有很多的步骤和行动,但是其中一定会有你需要首先去做的事情,这样的事情就应该被记录在“下一步行动”列表上。较好的 做法是把这些事项根据能够被完成的“环境”整理分类,例如“在办公室”,“用电话”,“在商场”.

项目(Projects) – 每个需要多于一个实际的行动才能达到的生活或者工作中的“开放式回路”就是一个“项目”.使用跟踪以及周期性的回顾来确保每个项目 都有一个下一步的行动进行下去。

等待(Waiting for) – 当你已经指派了一个事项给其他人或者在项目进行下去之前需要等待外部的事件,就应当在你的系统当中跟踪以及定期检查是否已经可 以采取行动或者需要发出一个提醒。

将来/可能(Someday/Maybe) – 这些事情你需要在某个点去做,但是不是马上。例如:“学习中文”,或者“进行一个潜水假期”.
对于跟踪你的预约和委托,一个日历也是重要的;另外,Allen特别推荐日历应该被用在他所谓的“硬工程”上:必须在某个特定的期限之前完成的事情,或者在约定的时间和地点完成的会议和约会.“待办”事项应该用在下一步行动列表当中。
GTD的最后一个关键组织模块是归档系统.
“Getting Things Done”书里说如果要用一个归档系统,那它必须得是简单易用和有趣。即使是一张纸,如果你需要用来记录参考信息,如果不属于你已经有的一个目录,也要有自己的文件组织方式。Allen的建议是你可以维护一个按照字母顺序组织的归档系统,这样可以比较容易快速的存储和提取你所想要的信息。Google的 Gmail的用户可以用创建标签的方式来创建“待办事项”和“项目”,这种方式在Bryan Murdaugh的 “Getting Things Done with Gmail” [1]白皮书中有清楚的描述。它保留了很多GTD的相同概念,但是是在在线的 电子邮件系统中实施。

检查

如果你不至少每天或者只要你有时间就回顾检查,那么你的行动和提醒的列表将会变的毫无用处。以你当时拥有的精力,资源和时间,决定什么是对你来说最重要的事情,然后做。如果你倾向于拖延,你可能会老是做最容易的事情,避免那些难的。为了解决这个问题,你可以一个接一个地做列表上的事情,按照它们的顺序,就象你处理你的收件箱一样。
至少以星期为周期,GTD要求你回顾所有你比较主要的“行动”,“项目”和“等待”的事项,确保所有的新任务或者即将到来的事件都进入你的系统,而且所有的事情都更新到符合最新的情况。Allen建议制作一个难题档案来帮助你更新你关于主要行动的记忆。

如果你把你的时间都花在组织工作,而不是做它们,那么所有的GTD系统都是不好用的!David Allen的观点是,如果你可以把必须做的事情,让它变得简单、容易、有趣的话,那你就比较不会拖延、或者被太多的“开放性回路”所压倒。

GTD的理念

GTD的核心理念在于只有将你心中所想的所有的事情都写下来并且安排好下一步的计划,你才能够心无挂念,全力以赴地做好目前的工作,提高效率。
而当你总是有些事萦绕在心头,悬而未决的时候,你要么就是会不时地想起它而影响现在的工作,要么就是会忘记了去做。
而GTD通过将所有的这些事都罗列出来再进行分类,确定下一步的处理方法,将所有这些悬而未决之事都纳入我们可控制的一个管理体系中。
GTD 认为人生最大的不安的来源不是事情太多,而是有很多事情你该做却没有做,你跟人说了你要做却没有做。GTD就是要确保你所有该做 的事情都做到。DavidAllen认为,压力不是来自任务本身,而是任务在大脑里的混沌塞积,造成心理的焦虑和抵触。我们要做 的,就是逐一清点大脑里的这些事务,将所有未尽事宜通通捕获并收集在大脑之外的文件系统中,比如实实在在的工具篮、纸质记事簿、电子记事簿 和邮箱等。 GTD的理念在于只有将你心中所想的所有的事情都写下来并且安排好下一步的计划,你才能够心无挂念,全力以赴地做好目前的 工作,提高效率。GTD 其实就是两点:
1. 清空你大脑的内存: 通常一件事情在你脑袋里所占的空间大小和你现实中已经完成多少成反比。把所有要做的事情分门别类,另外 存放在一个逻辑性强而又可靠的系统中去。大脑是用来思考的,不是用来记事的。我们的大脑每天耗费太多时间提醒我们该做又没做 的事情,应该把大脑从这种思维中解放出来。
2. 把任何任务和项目具体成行动: 不管是什么任务项目,我们要问的问题是下一个动作是什么?只有这样才能把计划具体化,才能让我们随时把握该 做什么。这样一来,在一个给定时间具体采取一个给定行动(action)的时候,我们才能做出最好的选择,而且对自己的行动选择有信心。

 

上周二在看某个博客的时候看到了这篇文章: 杂谈现代高级编程语言

其中有一个说法值得我们去思考: 什么是面向对象?

OOP (Object-oriented programming) 曾经无比风光, 在所有大学的教课书中都对这个名词有着很系统很详尽的解释, 甚至我看过一套有20个ppt的课程, 整个topic就是在诠释什么叫OO, 怎样OO的编程.

OO的兴起和JAVA的兴起不无关系, 虽然CPP是各大高校的基础教材, 但CPP在实际工程中的江河日下是有目共睹的, 没有多少个成功的项目是用的CPP, 企业级应用更加是JAVA的天下. 曾经被认为是CPP 最后一片绿洲的游戏业近年来也是被脚本语言一统江湖. 但是, 不可否认的是CPP 把OO的概念刻在了大家的脑海中, 觉得CPP 这样对OO 的封装, 才算得上OO.

最近接触了Objective-C, 和上面博文的作者得到的结论类似: 消息才是OO的本质.

"早在1998年,OO之父Alan Kay就曾经在一篇 邮件中说,他很后悔发明了“object”这个词,从而误导大家,把注意力都集中到“封装”,而忽视了OO的本质——messaging(消息传递)。Alan Kay的原话是:"

The big idea is “messaging” … . The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.

从Go Lang把class 这个概念去掉就可以知道, Cpp 所描述的那一套OO 思想已经逐渐被现代编程语言摒弃, 取而代之的是更方便更灵活的消息传递机制. 随着硬件的不断发展, 动态也正在成为主流, 灵活性带来开发的便利已经足以弥补静态带来的性能提升.

本周选的这个话题比较大, 要讲可以讲几天也不为过, 这里仅仅是抛砖引玉, 希望能为开阔提供点思路, 重新思考下OO的真正含义.

© 2011 Life N' Tech brought to you by @jaconey Suffusion theme by Sayontan Sinha