我最近思考做一个这样的东东(可能市场上已经有了,没做调研,目前只是在琢磨假设我做,我会怎么做):
需求--一个中产阶级家庭,上班,家里没人。可以通过摄像头监控重要地方。需要这样一个东西,每天回到家后打开监控录像,看有没有特别事件发生。一条条的拉着看得看多久啊。如果录像能够自动提示在几点几点有动静该有多好啊!这东东对办公室环境非常有用。
看起来比较难做,首先面临的是这样一个问题:
需要对数G的录像进行识别和搜索,计算量很大。每次看的时候要"预热"大几十分钟,那还得了。
(1)方案选择
解决方案其实很简单--把计算量分摊,在录像的时候进行识别,建立索引。什么运动检测,拓扑检测那一大堆我现在不懂的东西。如果性能还跟不上,可降低分辨率和/或隔几帧进行一次。
这一个决策应该比较关键。如果选择先录下来,再进行检索,那肯定个批了,满足不了需求。
(2)语言选择
不选C。因为索引结构可能需要特殊的数据结构,用C写工作量可能很大。选择c#/java具有一定的风险(性能上有风险,还有反编译的难度低)。鉴于可用的一些图象识别库差不多都是c/c++的,说不定将来选用哪个库,包一下的工作量不小。选择c++是比较保守适中。
(3)库的选择及基本架构
找一个能录像的,一个识别物体的(在sf.net上就发现了一个识别人的比较好的东东),能识别运动的,先把这三个搭起来形成一个demo,建立自己的索引体系结构,索引体系应该包括两点:1是静态对象的索引,2是由静态对象分析得到的运动的索引。接口设计好点,以便于后来换底层的几个库。但具体结构也就这样子了。上层来一个GUI,读取动态索引,根据索引位置调录像。
(4)确定几个主要的应用场景做为测试场景,测试,调整,使其有用。
这样的方案确定以后,基本就把项目风险连消带打的消除差不多了。心中有一定的把握了。如此一来,项目被分成5块:录像部分,静态识别部分,动态识别部分,索引部分,GUI部分。GUI部分没有风险。前三部分都有风险,但是风险比较小。大体都有开源成型物。不是GPL的拿来直接用,是GPL的不想开源自己读懂了重新写。第四部分有一定的风险,其实也没什么,不就是一个索引嘛。
只会c或者java?这不是换语言的理由。学习C++导致的成本和风险远比采用熟悉的语言来的小。
然后就是选择人选,学库,学API,选择数据结构,选择算法,修改算法,制定策略,暴露参数,用场景测试策略与参数。同时另一条线开始写GUI。项目的过程控制等等。
以上是我想象的一个例子,但应该比较接近现实。
就该例子而言,我觉得了解一个语言,很关键的一点是了解语言的编译模型,运行时模型,编程模型,工具支持,库的支持,关键API,主要优缺点及可能的弥补方案,在此基础上进行的方案制定,技术选型,架构控制,功能设计。这些是非常有价值的东西,在书本中学到的不多。一种很有效的学习方式是分析现有软件的设计。此外就是个人不断的总结。如何多快好省的跑向需求。这是第一层面的问题。
第二层面就是考虑设计与控制功能,性能,封装,抽象,开发过程,类设计,可维护性考虑等等。这涉及到对语言的编程模型,编译模型,内存模型,关键工具和库的更深入的了解。我现在管理项目的原则主要有以下几点:
(1)开发过程的自动化,涉及到自动构建,文档生成,单元测试,版本管理......很多问题。我现在要求坚持这样的原则:少写注释,多写文档,文档写在源代码里面。多写makefile。每一个cpp基本对应一个测试用例,确保这个源程序的质量。
(2)抽象与封装。目前最主要的体会是分层。分层分好后不同的层一般都有类似的开源实现,可以直接塞进来。不行就换一个。实在不行才自己写。抽象要尽量抽象到逻辑层次上,尽量减少语义差距。这个主要是经验问题,水太深了,和程序的编程模型相关。对于C++来说,四种编程模型应该清楚。命名的话我是越长越好,只要不是长的实在过分。
(3)选择关键的数据结构,这个对性能,封装等等有很大的影响。数据结构选择时最好成可插拔的方案,项目初期可能选择最简单的数据结构,后期可能换成复杂的数据结构,或者自己写的数据结构。
(4)选择关键的算法。一般项目用不到,难的项目可能用到,但一个项目中一般只会用到少数一两个关键算法。用什么查论文就行了。
(5)熟悉资源模型:几种关键的资源,CPU(进程,线程),内存,网络,硬盘及其它设备,熟悉常见的资源调度方法。
(6)熟悉选用的工具/库/重要的API。
第三个层面应该是具体的实现层面,类应该怎么设计,内存管理,问题解决,Bug调试这些实作层面的东东。这些问题,书中或google基本都有答案。书上原则性的东西又多一点,google到的实作层面的多一些。
就我个人对项目/产品开发的理解,中小型研发型项目成功的关键除去需求因素,主要在于第一二层面。项目的风险和进度和这个关系很大。第三个层面对成本影响很大,对项目的风险和进度影响也不大。第一,二层面好的设计,要求具备第三层面技能的程序员较少,对程序员的技能要求也不高,能大幅度消减人力成本。第一,二层面设计不好,则要求具备第三层面技能的程序员较多,对程序员的技能要求也高。第一二层面的设计,需要考虑成本因素。设计好的话,减少2/3的开发成本都是可能的。