逝水流年

This is a blog to record my life, my work, my feeling …

程序员不是操作工

故事的背景是这样的,我的一个朋友跟我聊天中说到他前几天加班到凌晨,手都疼了。我就问问加班干什么呢?他说就光Ctrl-CCtrl-V的弄了3000多次!我的天啊!怪不得手指头都疼了呢!

真正的程序员真的不是代码工人,是靠脑力而不是靠体力,是赚智慧的钱,而不是赚苦力的钱。那么真正的程序员应该怎么做呢?

  • 避免重复劳动,遇到类似需要大量Ctrl-CCtrl-V的情况,一定是程序架构出了问题,该做的公司是要思考为什么会出现这种不合理的情况?要从根本上杜绝这类情况的出现。

  • 善于利用脚本,脚本语言的简单和易用性是程序员工作中不可缺少的好帮手。善于用脚本创造各种工具来帮助程序员提高工作效率。上述情况完全可以写个脚本来做这些重复的工作。而且后期可以将脚本完善,做成个通用的工具,分享给同事,即利己也利团队,更可以增加你在领导眼里的不可替代性。

    现在的程序员门槛已经非常低了,但是不能因为门槛低就对自己要求降低。程序员不是码农,不是代码蓝领!我们是在改变世界,是高科技工程师!让我们做真正的程序员,而不是代码操作工!

浅析移动开发

这里只介绍笔者开发过的几个平台(iPhone, Android, Windows phone, Blackberry)。将从以下几个角度进行介绍: . 开发语言 . IDE . 模拟器 . 编译及调试 *. 开发成本

开发语言

iPhone:Object-C, C/C++

Android:XML, java, C/C++(NDK)

WP:XAML, C#, C++/CX

BlackBerry:KML, C/C++

可以分成两类:

一是iPhone;

二是其他三种。前者是完全native开发,并且只能在Mac OS X下开发(尽管现在有Xamarin但其跟官方API同步问题是个大问题);而其他三类,可以看出来,前端都使用类XML的语言开发UI,后端采用各自的开发语言,当然也可以使用native开发,但从目前来看对native的支持都不如原生语言支持的好。

IDE

iPhone: 首推XCode

AndroidEclipse目前还是主流;谷歌目前推出的Adroid Studio市场还未打开,以后不好说。

Widnows PhoneVisual Studio是不二人选啊!

BlackBerry:自带IED,是将Eclipse及所需插件打包到一起的一个IDE,可以归到Eclipse一类。

 从IDE的易用性和功能性来看,Visual Studio是当之无愧的第一名,xcode应该说是紧随其后,两个IDE都非常强大,但是xcode会有随机的crash,稳定性上还是不如Visual Studio,而且VS可以调试C#和C/C++,而eclipse调试native上非常麻烦,不是三言两语可以说明白的,有感兴趣的童鞋可以去网上找找。至于BlackBerry的IDE集成的插件还可以,调试native代码也还行,功能也比较强大,但是在调试的速度上实在是无法忍受。

模拟器 xcode的模拟器和WP的模拟器安装都是随SDK安装的,使用起来非常方便。而android的模拟器和Blackberry的模拟器笔者没用过,但是BlackBerry的模拟器安装却非常麻烦,又得折腾VM使用起来还经常断开,所以说在后两者上有条件还是真机调试的比较好。 编译及调试

XCode:可以同时调试Objective-CC/C++,编译速度还算比较快。

Visual Studio:如此强大的IDE,同时调试C#C/C++

Android:如果是java代码,速度和调试都挺方便的,但是如果想编译和调试native代码,那就需要有足够的耐心了,尤其是调试,配置之麻烦当属第一。

BlackBerry:编译速度十分慢,调试启动也很慢,但是启动后调试还可以接受的,比起android来,省去了很多配置的麻烦。

开发成本

● iPhone:投资比较大,光是注册开发者账号就需要99刀,而且还需要一台苹果设备,属于高富帅玩法。

● Windows Phone:投资一般,只用花注册的钱(如果要是用盗版VS的话),光VS的投资也不是小数。

● Adnroid:投资小,只需要一台PC和一台Android手机即可。可谓是专门给屌丝开发者准备的。

● BlackBerry:不熟悉,目前国内做的太少,而且BB10也没有在国内发售呢。

总的来说,做为一名移动开发者来说,如果没有一定的经济实力的话还是选择iPhone开发比较好,至少在经济收入上更可观一些;但是目前的情形上来说,安卓的市场是越来越大,说明做安卓的开发前途至少会越来越光明。至于WP,目前还需要观望;至于BB,就算了吧。

开源小游戏-基于android Sample Snake

最近利用业余时间学校android应用的开发,发现android sdk的sample中有个snake的小游戏,感觉不错,但是由于该游戏不能在触摸屏上玩,所以就萌生了自己动手的想法。利用2天时间又增加了用户排名和帮助等功能。程序已经托管到github上面,咱也玩吧开源。 地址:https://github.com/TimBao/Android_Snake 有感兴趣的朋友可以一同开发噢!

对比国内外的git开源项目

最近看到CSDN也有了自己的code(git),而且开源中国比之还早有git@ocs,这两个基本是跟github差不多,或者说是copy github。这里不说他们到底是谁copy谁,只单单谈谈里面到项目。浏览里一边C/C++的项目,发现CSDN到大多说都是垃圾项目,而且基本都不怎么维护,着实让人失望。相比ocs到还好一点,但多数项目也是为了凑数,维护人员基本都没有维护,真是很可惜。开源在中国这个土壤上说的比做的好,唱的比干到好!失望!失望!

Android NDK之JNI陷阱

背景: 最近一个月一直在做移植库的工作,将c代码到share library移植到Android平台。这就涉及到Android NDK(native develop kit)内容。这里只想记录下JNI(java native interface)经常遇到到问题。

问题1.  忘记delete local reference。带New到方法(如:NewByteArray)这样到方法比较好辨认,需要手动调用DeleteLocalRef()来释放(返回值除外)。比较特殊的一个方法是:GetByteArrayELement必须要调用ReleaseByteArrayElements进行释放。当然如果你只是取bytearray中到byte,那么完全可以用GetByteArrayRegion实现。

问题2. 没有NewGlobalRef。 在不同线程调用java方法,需要保存jobject对象,这时需要对jobject对象做全局引用,否则会失效。

问题3.  jbytearray的length。在JNI layer获取到jbytearray到长度是不对到,应该由java获取byte[]的length再传给C layer。否则C layer有可能获得到是乱码。

问题4.  线程问题。 不同线程使用JNIEnv*对象,需要AttachCurrentThread将env挂到当前线程,否则无法使用env。

问题5.  javap 命令是对java的class文件操作;而javah命令需要在包名到上一层路径运行才行,否则无法生成.h文件。

问题6. 尽量避免频繁调用JNI或者是使用JNI传输大量到数据。

问题7. Reference Table overflow (max=1024) 或者是 Reference Table overflow (max=512)一定是因为忘记释放global reference或者local reference,请仔细检查代码。

问题8. 不要在windows下使用cygwin编译NDK code,那样会遇到arguments too long问题,因为windows路径长度有限制导致。虽然可以使用subst将路径映射为短路径,但是在编译时间和调试上,windows到孩子都是伤不起。同样到build,在windows下要15分钟左右,而在mac下只要5分多,相差3倍。调试JNI 代码到速度更是不用提了,差太多。

总结,JNI代码量其实不是很多,JNI作为一个数据传输层,它到作用仅仅是java和c直接到桥梁,但是如果处理不好将会是灾难,调试和找bug非常困难。

Std::vector 两种操作的比较

  • swap
  • assign

    这里只想说明这二种操作的用处和效率。swap和assign都可以用在将一个vector的内容全部复制给另外一个vector,区别是swap会改变源vector,而assign会清空目的vector后再将源vector的值全部插入到目的vector中。就效率而言,swap只是交换vector的头指针,时间复杂度是常数;而assigin时间复杂度则是线性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <vector>
#include "DebugUtility.h"
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

void print(int x)
{
    cout << x << endl;
}

void Swap(vector<string>;& source, vector<string>;& dest)
{
    DebugUtility temp;
    dest.swap(source);
}

void Assign(vector<string>;& source, vector<string>;& dest)
{
    DebugUtility temp;
    dest.assign(source.begin(), source.end());
}

int main(int argc, const char *argv[])
{
    vector<string>; source(900000, "90");
    vector<string>; destination(1, "abc");
    Swap(source, destination);
    //source.clear();
    //for_each(destination.begin(), destination.end(), print);
    //Assign(source, destination);
    //source.clear();
    //for_each(destination.begin(), destination.end(), print);
    return 0;
}

结果: Total time elapsed : 1 us Total time elapsed : 12391 us

ps: DebugUtility.h  大家可以从https://github.com/timbao/material.git/utility取得。

Gvim Use Wmctrl in Ubuntu

Use the wmctrl tools could maximize the windows of gvim in ubuntu. But I find a small issue for that.

Here is the wrong script:

1
2
3
4
5
6
7
8
  if has("win32")
    au GUIEnter * simalt ~x
else
    au GUIEnter * call MaximizeWindow()
endif
function! MaximizeWindow()
    silent !wmctrl -r :ACTIVE: -b add, maximized_vert,maximized_horz
endfunction

You could see that between “,” and “maximized_vert” on line 8, there is a blank. It’s the reason why the script can’t works. So I remove the blank and it woks fine. So strange, because this scripts works well on my mac mini.

How to Use Terminal in Vim

这篇文章虽然叫做“如何在Vim中使用Terminal”,但是我这里要说的是在Windows下使用。

  • OS: Windows 8 64bit
  • Plugin:ConqueTerm.vim (该插件是利用socket与真正的terminal进行通信来操作terminal command的。插件是使用python写的)
  • Python:2.7
  • Vim:7.3

在我的Linux下使用ConqueTerm一点问题都没有,非常好用,我的32位的Window7 上面也没有问题,只有在64位windows 8工作机上才会出现无法在vim中找到python接口。也就是说 echo has(‘python’) = 0。通过查看vim的verison,发现已经打开了python/dyn。这个问题一连搞了一天也没有解决,果断放弃。这段时间vim的学习又有了突破,才又想起解决这个问题,通过大量的google search,终于在stackflow上面看到某人也有类似的问题,解决方法也是让我没有想到,重装vim或者python?为什么呢?原来是版本不匹配,我的机器安装的是64位的python,而vim确是32位的,果断下载一个64位的Vim,重新测试。OK,一切正常!

通过这个问题,我的收获就是当一个问题陷入死胡同的时候,不应该去放弃;可以暂时先放下,调整下心情状态,或者过段时间再来解决,很有可能就会柳暗花明又一村!

Pasting Code With Syntax Coloring in Emails Use VIM

今天跟T又学了一招,当邮件中包含code时,可以将code转换为html格式再发送,这样既整齐,又美观!不过T使用Emacs来制作的,偶Emacs不会,想用VIM来实现类似的功能,上网找到了这篇文章,原来VIM早就有了这种插件了。看来是我out了,要学习的东西还是太多啊!抓紧时间,持续学习,每天进步一点点,累计起来也是非常巨大的。就像最近微薄中有个公式:

1
2
1.01^365=37.78
0.99^365=0.0255

每天一点,一年后的变化差距有多大啊!!!!

Address

阅读代码的方法

过完年,工作有所调整,一下子忙了起来,要去接触全新的一块内容,最近一段时间是不停的trainings、read documents、watch codes。尽管每天都非常忙,回到家后还要坚持study English, 练习听力(因为每周要跟美国那边开会,所以英语听说已经是非常迫在眉睫了!)还要坚持锻炼身体,毕竟好身体是所有这些的前提。 先说说每天的时间安排吧:

  • 9:00 — 到公司后,一边吃早餐,一遍浏览下新闻和微博。
  • 9:30 — 开始看文档和代码。
  • 12:00 — 午饭
  • 1:00  —继续看代码和文档。
  • 2:00 —有可能有培训。
  • 6:00 — 下班回家
  • 9:00 — 听英语(看网易公开课或者是美剧,无字幕)训练英语(《千万不要学英语》中学来的方法)
  • 10:00 — 仰卧起坐或者俯卧撑锻炼。

目前的问题是,看代码的效率比较低,注意力集中基本在30分钟左右,而且没有什么条理。培训的内容加上自学的内容太多会导致有很多遗忘,或者是没有深入下去,过段时间又忘了。

今天抽出了一点时间好好思考了下到底应该如何去学习包括看代码才是高效的呢?

首先就是要有个整体的计划,虽然计划不如变化快,但大体方向不能变太大。

其次对代码要先总体再细节的看,1)将整体功能和单元文件都熟悉,包括大概流程;2)将代码划分几个部分(例如我从纵向区分把接口按照调用顺序从上到下进行分类),这点得益于代码命名的比较规范 3)一部分一部分看,看完后要对自己问问题,这点最重要,只有通过问题才能了解自己是否掌握了。这点我也是在训练中。

最后,要及时总结和记录,这样利于回顾和复习。这点我做的不是特别好。