Android手机收听播客的方法

  1. 在应用中心下载荔枝FM
    lizhiFM
  2. 搜索节目
    lizhiSearch

在搜索栏输入“新闻酸菜馆”,点击“搜索”,在“播客”栏中的第一个搜索结果就是。
lizhiSearchResult

  1. 收听节目
    点击进入,在“节目”栏就可以收听他们的历史节目了。
    lizhiSuancaiguan

如果想听高音质的节目需要注册:
lizhiSignup

点击“登录/注册”。使用下方的微信快速登录方式直接登录,之后就可以收听高音质版本的节目了:
lizhiSignupWeChat

如果手机没有安装微信/QQ,那么请使用手机号获取验证码注册后再登录。

  1. 其它推荐节目
  • 太医来了
    lizhiTaiyilaile
  • 科学脱口秀
    lizhiKexuetuokouxiu
  • 友的聊
    lizhiYoudeliao

还可以在“频道”栏中找自己感兴趣的播客/节目听:
lizhiChannel

lizhiChannelExtra

单片机程序设计的十层功力,你练到哪一层了?

Overview-RPi-netboot

第一层,我来了。

处在这一层的典型是可以用C语言写简单的逻辑控制,如闪烁LED,简单数码管显示,简单外围模块驱动实验。一般对单片机感兴趣,经常动手实践的人,半年左右,可以练到此地步(针对没有接触过单片机的人而言)。此层最典型的示例就是,扫描按键时候,检测按下——延时20ms –再次检测按下—-返回键值或等待释放。如果你是这样做的,或者正在这样做,毫无悬念,应该处于这个级别。对于95%的电类专业学生来说,毕业时候,远远低于这个级别,剩下的5%则依次分布在各层上。这也是为什么学单片机的人成千上万,而会用的人寥寥无几的原因。

第二层 真的打呀。

步入这一层的典型标志就是开始思考自己所写的程序是否能够有一点实用价值。譬如应用在实际工程项目中。在这一层,应该开始思考如何让程序结构简单模块化,如何合理的利用CPU的时间。我曾经写过这一层的一点简单教程。对付这一层应该是绰绰有余了。

第三层 并肩作战,时间,说爱你不容易。

这一层是建立在第二层的基础上面。从第二层跨越到这一层,需要很多代码行的积累。在这一层,你对系统中的各个模块应该能够很好的区分。同时对于时间的应用安排更加合理。在这一层,同时也应该考虑时间驱动的设计模式。如何让CPU更有效率的利用起来,需要长时间的积累,并非看,想就可以弄明白,而是不断的实践。

第四层 状态,你在哪里。

这一层同样建立在第三层基础之上。掌握了以上三层,只要基本不涉及复杂算法的程序,可以组织小规模的程序的编写了。在这个时候,如何有效区分系统中的状态,利用状态来进行迁移,变得尤为重要。有人说通用结构好。反而我认为,针对特定应用来规划更优秀。对于单片机程序而言,几乎没有能够一摸一样的项目。而对于可移植性而言,能够做到函数级别的复用,已经非常难能可贵了。

第五层 时间,还是时间。

时间具备精确性、模糊性、可丢失性,这三个特性是从应用时间的不同角度来描述的。精确性应用在精确地定时、计时的场合,它是个强实时的概念,比如测量频率。模糊性应用在需要稳定计时的场合,它追求的是长时间的稳定性,而忽略定时每刻发生的时刻,比如显示日期时间。可丢失性是非重要的计时,它只要求阶段性时间符合而不要求一定时间到达就必定发生,比如LED闪烁的时间控制、倒计时执行某些功能性操作,通常是使用时间系统的时间发生标志。同时在这一层如果能够将WINDOWS程序设计中的一些优秀思想利用起来,则非常好。能够领悟到这一层的,在我所知道的前辈高手中少之又少。

第六层 丰富你的视界。

这一层是我自己安排的位置。相比前面几层而言,我觉得它更为重要。写单片机程序,什么最痛苦,当然是做界面最痛苦。一个好的产品,离不开好的UI。在这里,你需要设计简单易用同时好看的人机接口非常不容易。而且对于简单单色点阵液晶的操作,能够做到显示界面非常好看,同时程序结构清晰,非常不容易。很多人都说,设计界面,就像绣花似的。太痛苦了。我一直在折腾,现在还没有一个定论,到底是通用的结构好,还是针对特定用途还设计好。按照我在第四层中的说法,这里应该根据特定用途来规划更好些。

第七层 我们说好的。

这一层主要是各种各样的协议的熟悉。非常重要,因为这个是和实际联系最为紧密的。工业现场的各种传感器,采集仪表如何将采集到的数据有效的发回给上位机。两者能够可靠的通信,软件层面上都离不开它们。

第八层 别争了,让我来分配吧。

还在为该如何分配CPU的时间嘛。其实不用苦恼。千万不要什么东西都重新自己造。你想开车,不用自己造轮子吧,买一个就可以了。前人其实对这些问题都研究过非常多了。因此操作系统应运而生。有人说,如果学会了在操作系统上面写程序,将绝不想再回到以前的那种编程方式,听起来非常诱人。

第九层 穿着操作系统去裸奔。

啥,都用上操作系统了,还想着裸奔。太花心了吧。非也。这里是将前面几层所提及到的一些思想与第八层融汇贯通。可以说,在这一层,需要对前面的每一层都非常的熟悉。并经过很多实际项目的磨练方能有所体会。

第十层 无招胜有招。

能够达到这一层的应该算的上是屈指可数的高手之一了。在这一层上,除了前面九层的熟练应用之外。更牛的人应该是可以设计操作系统,设计gui之类的。要达到这一点,需要非常多的基础知识,以及大量的专业知识以及实践,再加以10—20年的实战经验,以及一颗不沉寂的心。在这里,无招胜有招,非常熟悉MCU的特性,能够利用这种各样的技巧。这样的高人,在国内数一数二的电子论坛里也不在少数。

单片机的本质只是一个工具。因此,更为重要的是模拟电子,数字电子以及其它基础的专业课程。很多人都说大学学的东西没有用,其实这个才是最大的谬论。万丈高楼平地起,没有这些专业基础课程的支撑。以后工作中进步非常缓慢。道理很简单。学的东西都是建立在以前的基础课程上面的。如果一个连三极管的放大电路都不会分析的人,我不相信他可以设计出优秀的电路来。因此作为一个合格的电子工程师,除了掌握广泛的专业知识技能外,时刻不能够停止学习的脚步。

Link: http://www.21ic.com/jichuzhishi/mcu/questions/2015-02-02/614962.html

对BOR,POR和PUC的理解

MSP430x5xx有三种复位信号:掉电复位(brownout reset, BOR)、上电 复位(power on reset, POR)和上电清除(power up clear, PUC)。下表列出了三种信号的触发条件和信号产生后设备的初始条件:
表1
在系统完成复位以后,用户软件必须根据应用需求初始化设备:

  • 初始化堆栈指针,一般是写入RAM顶端地址;
  • 根据应用需求初始化看门狗;
  • 根据应用需求配置外围模块。

对BOR的理解

在单片机系统中,一般采用电池或者市电供电。如果采用电池供电,则存在电池电压不断下降的问题;如果采用市电供电,则存在着电压波动和电源干扰的问题。其中,电源电压的不稳定,是造成单片机系统运行混乱甚至死机的重要原因之一。所以,通过BOR电路检测电源的电压, 一旦发现VCC下降到某一个门槛值时,就使单片机及时复位以免系统失控。这个复位状态一直保持到VCC重新上升到门槛值以上之后。

对BOR, POR和PUC之间区别与联系的理解

图1
BOR会在芯片上电或者掉电过程中检测电源电压,并产生POR信号,如上图所示。芯片上电过程中,当电源电压VCC超过VCC(start)后BOR电路产生POR信号,直到VCC超过V(B_IT+),然后再经过延迟t(BOR)后,POR信号撤销。如果VCC电压上升速率较慢,t(BOR)会相应的延长。芯片掉电过程中,VCC必须降到低于V(B_IT-)之后BOR电路才产生POR信号。这是个迟滞比较功能,V(B_IT+)和V(B_IT-)差值即为迟滞电压Vhys(B_IT-),通过迟滞比较避免错误产生POR信号。
BOR与POR(和PUC)信号一个重要不同之处在于POR和PUC信号不会造成芯片执行启动代码,即程序计数器(PC)会直接载入0xFFFEh地址。另一个重要的不同之处在于BOR、POR和PUC信号系统复位后会导致不同的寄存器初始值,如下表最后4行所示。
图2
例如SYSCTL寄存器的SYSJTAGPIN、SYSPMMPE和SYSRIVECT位的值保持置1直到系统产生BOR信号。
图3
下图用图形方式展示了BOR、POR和PUC的产生条件和三个信号之间的关系。可以看出BOR信号能够产生POR信号,POR信号能够产生PUC信号,但反之不然。
图4

参考资料

在CentOS里安装Python3

  1. 安装环境
    yum install gcc
    yum install zlib-devel
    yum install make
    yum install readline-devel
  2. 下载python版本
    wget http://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz
  3. 解压缩、编译和安装
    tar -zxvf Python-3.4.0.tgz
    cd Python-3.4.0
    ./configure –prefix=/opt/python3
    make all
    make install
    清除之前编译的可执行文件及配置文件。
    make clean
    清除所有生成的文件
    make distclean
  4. 查看安装的新版本信息
    /opt/python3/bin/python3 -V
    Python 3.4.0
    由此看出编译安装的新版本python生效了
  5. 做个软连接到当前用户的bin目录
    此时,新版本的python没有覆盖原来的版本,先将原来的python重命名
    mv /usr/bin/python /usr/bin/python_old
    重新建立超链接
    ln -s /opt/python3/bin/python3 /usr/bin/python3
    再次打开python则显示新版本
    python

    Python 3.4.3 (default, Oct 12 2015, 21:31:59)
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-16)] on linux
    Type “help”, “copyright”, “credits” or “license” for more information.

  6. 升级安装好新版本python以后,默认依然是python2.6
    vi /usr/bin/yum
    将文件头部的#!/usr/bin/python修改为 #!/opt/python3/bin/python3或#!/usr/bin/python3即可。

说明

问题一:

python3命令进入到交互界面,结果发现,退格键,方向键等好多键都不能正常使用,

解决办法:

安装readline-devel修复解决

问题二:

yum  
File "/usr/bin/yum", line 30  
except KeyboardInterrupt, e:   
                         ^  
SyntaxError: invalid syntax  
原因:

这是因为yum采用python作为命令解释器,这可以从/usr/bin/yum文件中第一行#!/usr/bin/python发现。而python版本之间兼容性不太好,使得2.X版本与3.X版本之间存在语法不一致问题。当系统将python升级到3.X后,出现语法解释错误。

解决办法:

很简单,一是升级yum,一是修改yum的解释器为旧版本python2.6(如果你没有采用覆盖升级的话)。
升级yum的作法就不详述了。修改yum的解释器为旧版本python2.6:
$ vi /usr/bin/yum
将第一行”#!/usr/bin/python” 改为 “#!/usr/bin/python_old”即可。

JavaScript陷阱

1. 动态类型

JavaScript是一种松散类型的语言。换句话说,不必提前声明保存在变量中的数据是什么类型。Java(跟JavaScript完全不一样)等其他语言都要求提前声明变量类型,比如int、float、boolean 或String:

// 在Java中声明变量
int number = 5;
float value = 12.3467;
boolean active = true;
String text = "Crystal clear";

而JavaScript则会根据赋给变量的数据,自动推断其类型。(注意,’’或”” 表示字符串。我个人喜欢双引号,但有人喜欢单引号。)

// 在JavaScript中声明变量
var number = 5;
var value = 12.3467;
var active = true;
var text = "Crystal clear";

好讨厌哪,那么多var!不过也有方便的地方:不用知道保存什么数据,就可以声明和命名变量。甚至随意改变保存的数据类型,JavaScript也不会怪你:

var value = 100;
value = 99.9999;
value = false;
value = "This can’t possibly work.";
value = "Argh, it does work! No errorzzzz!";

这里要提醒大家的是,如果你不小心在一个数值变量里保存了一个字符串,后来代码就出现了一些奇怪的问题,希望你自己能好好反省一下。如果你不确定某个变量中保存着什么类型的数据,可以使用typeof操作符:

typeof 67; // 返回"number"
var myName = "Scott";
typeof myName; // 返回"string"
myName = true;
typeof myName; // 返回"boolean"

2. 变量提升

在我们印象里,浏览器会从上到下依次执行JavaScript代码。但有时候也不一定!比如,下面这些代码,你觉得变量i什么时候有定义?

var numLoops = 100;
for (var i = 0; i < numLoops; i++) {
console.log(i);
}

在其他很多语言中,i会到for循环开始时才被声明,这符合我们的预期。但由于存在一种叫做变量提升的机制,JavaScript中的变量声明会被提升到函数上下文的顶部。对于前面的例子来说,i实际上在for循环开始之前就有了定义。下面的代码跟上面的代码是等价的:

var numLoops = 100;
var i;
for (i = 0; i < numLoops; i++) {
console.log(i);
}

如果变量名字有冲突,变量提升可能就会带来问题。因为你本以为某个变量到后面才会有定义,不成想它早在代码一开始执行时就有定义了。

3. 函数级作用域

在编程领域,变量作用域这个概念用于区分在哪个环境下可以访问哪些变量。一般来说,在任何地方都能访问任何值是不正确的。因为这样发生冲突的可能性太高,或者不知道在哪儿意外改了某个值,都会让你急得疯掉。

很多语言都有块级作用域,也就是在当前“块”中,变量才有定义。这里的“块”,通常就是花括号。在块级作用域下,前面例子中的变量i将只存在于for循环中。如果想在循环外部读取或修改i的值,都会失败。这样其实挺好,因为你知道循环中的变量不会跟循环外部的其他变量有冲突。

但是,JavaScript中的变量只能限制在函数中,即在函数(而不是任何块)中声明的变量只能在函数内部访问。

假如你使用过其他语言,那么对这一点必须格外注意。关键要记住:要想封闭某个值,就得把它们放到函数里。

4. 全局命名空间

说到变量冲突,请帮我个忙:打开任意网页,调出JavaScript控制台,输入window,然后单击那个灰色三角形,看看里面都有什么。

我知道你就像进入了迷宫一样,而这正是所谓的“全局命名空间”,真是“百闻不如一见”

window在浏览器中是一个顶级对象,包含所有JavaScript中能直接访问到的对象。你看到的所有这些对象和值都包含在全局作用域中。换句话说,如果你每次都在全局作用域中声明新变量,那这个变量就会被加到window对象下面。正像一些JavaScript界敢于仗义直言的人所说:“你这是在污染全局命名空间。”(奇怪的是,很多在论坛里义正词严说这种话的人,在现实当中都很平易近人。)

比如,我们在控制台中输入:var zebras = “amazing”。

然后,再输入window,点开灰色小三角,一直向下滚动,滚动到最底部,就会看到zebras。

(让人不解的是,在JavaScript中不使用标准的var也可以定义新变量。因此,只要输入zebras = “amazing” 也会得到与前面相同的结果。)

给window增加几个值有什么大问题吗?刚开始的时候,啥事儿也没有。但随着你的项目越来越复杂,特别是在需要联合使用非D3的JavaScript代码时(如jQuery、Facebook 的“Like”按钮,或谷歌的分析跟踪代码),说不定就会发生命名冲突。比如,你在自己的项目里使用了变量zebras,而zebraTracker.js恰好也使用了一个同名变量!结果肯定是一团糟。至少,一些不太规范的数据,很有可能导致你的代
码发生异常或错误。

解决这个问题有两个简单的办法(说明一下,不到后面你不用担心这一点)。

只在函数里面声明变量。虽然有时候也不是绝对可行,但函数级作用域可以防止其本地变量跟其他变量发生冲突。只声明一个全局对象,然后把你本来想作为全局变量的值都作为这个对象的属性。比如:

var Vis = {}; // 声明空的全局对象
Vis.zebras = "still pretty amazing";
Vis.monkeys = "too funny LOL";
Vis.fish = "you know, not bad";

这样,所有变量就都被“关在笼子里了”(在这里就是全局对象Vis里),因此不会再污染全局命名空间。当然,不一定非得叫Vis,叫什么随你便——不过叫Menagerie(动物园)输入起来就太麻烦了。无论如何,如果再有冲突发生,那肯定是其他脚本里也恰好有一个全局对象,而且也起了个相同的名字(Vis)。但这种事儿发生的概率就低得多了。

摘自《数据可视化实战:使用D3设计交互式图表》

让代码在Word中更漂亮

方法一:

第一步:插入一个1行1列的表格,然后将代码写在里面;

第二步:完成之后选中表格,单击菜单格式——>样式和格式 ,在打开的任务窗格中,单击“显示”下拉列表框,选择“所有样式”,然后在上面的列表中找到“HTML代码”,单击一下,这样效果就比较好了。

具体操作如下图:

效果图:

方法二 :

利用notepad++处理代码(支持多国语言,安装时可选择汉语)

Notepad++下载地址http://pan.baidu.com/share/link?shareid=420233&uk=1075514814

第一步:将它复制到notepad++[1]上。

第二步:设置语言关联,【语言->C】,此时代码高亮生效。

第三步:点击插件(Plugins)->NppExport->Copy HTML to clipboard复制到剪贴板;

或者如下图操作:

在word中粘贴,最后效果如下:

[1] Notepad++是一套非常有特色的自由软件的纯文字编辑器(许可证:GPL),有完整的中文化接口及支援多国语言撰写的功能(UTF8 技术)。它的功能比 Windows 中的 Notepad(记事簿)强大,除了可以用来制作一般的纯文字说明文件,也十分适合当作撰写电脑程序的编辑器。Notepad++ 不仅有语法高亮度显示,也有语法折叠功能,并且支援宏以及扩充基本功能的外挂模组。

骑行的分析性报告

东部大伟哥的成果,本人只是稍微整理

物品准备:

  1. 装备:自行车(美利达或捷安特一部),冲锋衣(防雨,专业骑行的衣服),照相机,偏光墨镜,头盔,口罩,车载强光手电筒;

  2. 修理工具箱:内六角,套筒,扳手,各种型号螺丝刀,机油;

  3. 食物:水,火腿肠,面包;

  4. 生活用具:毛巾,牙刷,牙膏,卫生纸,几套干净衣服;

  5. 药品:感冒药,跌打损伤药,藿香正气水,板蓝根;

  6. 其他:移动电源(1万毫安左右),码表,匕首。

几个主要的问题:

  1. 据查,路线全长519公里,首选国道,每天路程如何行进?具体标志地点的寻找?

  2. 每天的补给站,根据手机不同,选用的移动电源可大概充4次电,出发时间和停止时间的规划?

  3. 遇到歹徒,没有信号的应急处理方案若干,匕首的选用或者?

  4. 根据时间的计划,7月初为开始时段,考虑到天气的因素,可能的医院或医护站地标?

  5. 修理的问题,万一路上链条的断裂,如何处理?在没有其它人的帮助下,可否自行处理?

  6. 现金携带的多少,万一没有青年旅社,是否考虑在农民家帐篷借宿?

  7. 因为是初次这样的绿色旅行,最好人数可以控制在多少左右,多了拖累进度,少了怕问题一来,无法解决,可否最佳寻找到已有经验的可靠人选带领?

  8. 目的地游览的小计划,这个可以路上商讨,具体?

每人初始费用评估:

  1. 自行车及安装在上的一切物品(包括强光手电,偏光墨镜,码表,自行挡板,头盔,口罩等等)2000(自行车可借,完全根据各人需要,但小物品务必聚齐);

  2. 修理工具箱(可以共用)30;

  3. 移动电源200;

  4. 冲锋衣1000(完全为了防雨,因为是夏季,但也可以考虑不购买);

  5. 生活用品及药品,食品自带,不列入考虑范围。

每人旅途费用评估:

根据行进天数而定,总花费估计在600左右,如果再接着骑至**,费用会有所涨幅。

尾言:

旅途每日计划暂时未出,敬请期待…..这是一个粗略的评估分析,在我多次跑了骑行店,问了很久原来的朋友之后…。预计6月份毕业,会开始着手备好一切先行通知几个人,希望你们几条汉子尽可能的参加进来,已经工作的我就不考虑了。如果还有汉子有兴趣,欢迎引之加入,有朋自远方来,不亦乐乎~我们就一起吧!如果有经验的朋友加入的话,就请他当我们的队长吧如果全部是纯小白,我就自告奋勇咯,那就给我一次做队长的机会吧,统筹一切,我们一起来经历,共同努力,提出你的看法,面对问题,好好享受对于我们每个特殊独立的生命的青春的这次挑战吧,相信到了很久以后,那会是我们很温暖的回忆人生何处不相逢,认识你们,是我的缘分。一骑绝尘,留岁月鉴之~

智能小车MATLAB仿真

现在关于matlab仿真的想法是分几个部分写程序:

目标路径部分、对象建模部分、控制器部分以及参杂在其中的绘图部分。

其中目标路径可以有不同的形式,点、直线、圆、S曲线等;

对象建模从简单的开始,从经典的二轮小车模型开始,在分别对舵机、电机建模,最后统一起来整体建模;

控制器先采用PID算法,再考虑模糊算法。

小车对象为一个多输入多输出的系统。

下午成果:

采用了P控制,对二轮小车的经典模型进行了控制仿真。

当去掉P时,小车路径仅为一点;若P作用越强,小车路径与目标路径偏差越大。去掉偏差,必须加入I作用。

程序如下:

clear all
close all
clc

ts=0.001;
for k=1:1:2000
xd(k)=cos((k-1)*pi*ts);
yd(k)=sin((k-1)*pi*ts);
thd(k)=ts*pi*(k-1)+pi/2;
end

u1(1)=0;u2(1)=0;
e1tmp=0;e2tmp=0;e3tmp=0;
y0=[0;0;pi/2]; 

for k=1:1:2000     
if k==1
    q=y0;
end        
xp(k)=q(1);
yp(k)=q(2);
thp(k)=q(3);

%current error of time k
qd=[xd(k);yd(k);thd(k)];
ce1(k)=qd(1)-q(1);
ce2(k)=qd(2)-q(2);
ce3(k)=qd(3)-q(3);
E=[ce1(k);ce2(k);ce3(k)];
B=ts*[cos(q(3)) 0
      sin(q(3)) 0
      0         1];

Kp=[100 100 100
    100 100 100];
Kd=[0 0 0
    0 0 0];
Ki=[10 10 10
    10 10 10];

if k==1
    Etmp=[e1tmp;e2tmp;e3tmp];       
    Ei=0;
end
Ep=E;Ed=(E-Etmp)/ts;Ei=Ei+E*ts;    
U=Kp*Ep+Kd*Ed+Ki*Ei;
u1(k)=U(1);u2(k)=U(2);
u=[u1(k);u2(k)];

q=q+B*u;

%error of previous time k+1 
e1(k)=cos(k*ts*pi)-q(1);
e2(k)=sin(k*ts*pi)-q(2);
e3(k)=ts*k*pi+pi/2-q(3);


Etmp=E;

end

figure(1);
hold on;
plot(xd,yd,'r',xp,yp,'b');
xlabel('xd xp');ylabel('yd yp');

figure(2)
hold on;
plot(xp,yp,'b');
xlabel('xp');ylabel('yp');

simualation result

技术路线的选择重要但不具有决定性

最近微软在技术上连续有大动作,在PDC上发布了Windows Azure云计算平台,预告了Visual Studio 2010、.NET 4.0和C# 4.0。如果放在几年前,我相信微软粉丝们一定是欢声雷动,不过这次情况有点不太一样,在网上看到有人在抱怨微软技术更新速度太快而且四面出击,还有人扬言要改弦更张,投奔Linux或者Java阵营。我本人也收到一封来信,写信人大意是说自己大学时选择.NET路线,一路跟下来很辛苦,2.0还没学好,人家已经4.0预览了,感到很困惑,问我该怎么办。老实讲,这样的问题我无法回答,每个人具体情况不同,所应该采取的态度和解决方案也不同。从我自己来讲,其实技术路线问题也曾长时间地困扰我,所以我想把我现在的一些想法摊出来跟大家分享一下。罗列如下:

1.根据我长期的观察,做开发技术的人按照其人生路线设计,可以分成几类。第一类是把自己的命运寄托在一项事业上。这样的人知道自己想干什么,而且有能力把技术当工具来实现自己的想法和事业。这里所说的事业是广义的,并不是说你非要自己开公司当老板,而是说你认可一件事情,比如促进人们交流和言论自由,带给大家更多娱乐,提升大众身心健康水平,增强国家国防实力,或者提升某个行业的信息化水平,然后你能够以技术为手段,在这个事情上做出成绩。这种人做着自己认为值得一生投入的事情,愿意领略这一追求带来的人生起伏并且无怨无悔,我认为这是做技术的最高层次。第二类是把自己的命运寄托在组织和团队上。这种人虽然不知道自己到底想干什么,但是技术水平出色,而且综合素质突出,勇于变化,能够把技术当敲门砖进入某个优秀的团队,以团队的目标为目标,依据团队的需求而转型或者坚持,跟团队一起干出一番成绩。这类人有令人羡慕的职业背景,在大公司里高薪厚禄,生活比较安定舒适,但是中年以后会经常自问到底做了什么自己想做的事情,为自己过于风平浪静的人生感到惆怅。但总的来说,这个层次也是比较高的。第三种是把命运寄托在技术上。这种人有能力成为技术的专家,然后就希望奇货可居,待价而沽,把技能当商品出售谋求富足人生。这种人没有大的人生目标,不想把自己的命运跟企业和组织绑定在一起,也不愿意做什么改变,只是满足于技术高手的层面,寄希望于其技术专长能够长期值钱,有点投机主义者的意思。第四种是还处于出卖劳动力的阶段,在这里就不多说了。

我想说的是,在过去很多年里,很多技术人实际上是把自己定位在第三种人里。而实际上,只有成为第一类和第二类人,才算达到了比较成功的状态。第三类人实际上最危险,因为技术的变迁不但是可能的,而且是一定的。他们要么马上被淘汰,要么追得老了累了追不动了以后被淘汰,被淘汰只是时间问题。 因此,如果你认为某个软件技术的兴起或者衰落对你个人的职业生涯构成了决定性的影响,那么你可能正走在错误的路线上,应当尽快改弦更张。

2.对个体软件人来说,什么是核心竞争力?不是时间差,不是技术,不是基本功,不是什么思想,也不是聪明脑瓜,而是你独特的个性知识经验组合。

有人看到新技术出来了,急急忙忙赶上去尝鲜,以为自己快人一步,就能如何如何,实际上这种想法根本不靠谱,最多在论坛博客上风光两天,等这项技术投入实际应用以后一点便宜也占不到。

有人把某个技术、框架、平台研究得里外通透,以为这样就能奇货可居。实践中,这种人能红火一时,但很难超过5年。这是现阶段技术发展生命周期所决定的。此外,现在越来越多人意识到了,能够靠读书看文章读代码做练习学会的东西没什么门槛,智力正常的人只要愿意花功夫,都不难达到你的程度。有的人认为,自己有能力驾驭技术潮流,哪个红学哪个。我在技术行业里不敢说阅人无数,见过的高手上百是有的,说句不怕得罪人的话,能够连续抓住两个以上的潮流并且始终处于领先位置的人及其少见,一只手就数的过来。更常见的情况是,上一个阶段的成功会成为下一个阶段的障碍,所谓随机应变屹立潮头之说,往往只不过是当红小生给自己壮胆的狂言,时过境迁之后,他就只能听着新一代当红小生的豪言壮语而默默苦笑。

有人强调基本功,这是对的。在任何技术性行业里都一样,基础打得多深,上面就能造得多高。现实中,基本功扎实的人很少见,这跟中国教育的弊病有关,所以基本功好的人,一般应变能力强,学习速度快,比较受欢迎。但说基本功是核心竞争力,还是没有抓住本质。我们经常能看到基本功差不多的两个人,一个发展的很好,一个发展平平,这表明基本功成功职业生涯的是重要条件,但不是决定因素。

有人强调这个那个思想,实际上软件行业里的伟大的思想就那么屈指可数的几个,窗户纸一点就破,其他衍生出来的思想,就跟技术风潮一样,各领风骚三五年,成不了你核心竞争力。

还有人强调自己的智商,聪明脑瓜,觉得自己比别人聪明,自己的聪明是核心竞争力。大学生、刚毕业的人持这个观点的比较多,然而有过人生阅历以后,自然会对这种观点不以为然。本质上这是因为社会对于“聪明”的定义与学校不同,一个解题高手在学校里可能是受人仰慕的聪明脑瓜,但在职业人生中则可能是个大傻蛋。我们身边很多人走了一条不尽如意的人生道路,往往不是因为他们不够“聪明”,而是因为他们太“聪明”了,聪明反被聪明误。我想这也是为什么人们要发明“智慧”这个词以区别于“聪明”的原因。另外,关于这种观点,还有一点不得不指出,那就是在软件这个行当里,一般聪明就可以了,绝顶聪明占不到多少便宜。

那么核心竞争力是什么?我观察圈子里很多成功和不成功的技术人,提出一个观点,那就是个人的核心竞争力是是他独特的个性知识经验组合。这个行业里拥挤着上百万聪明人,彼此之间真正的不同在哪里?不在于你学的是什么技术,学得多深,IQ多少,而在于你身上有别人没有的独特的个性、背景、知识和经验的组合。如果这种组合,1,绝无仅有;2,在实践中有价值,3,具有可持续发展性,那你就具备核心竞争力。因此,当设计自己的发展路线时,应当最大限度地加强和发挥自己独特的组合,而不是寻求单项的超越。而构建自己独特组合的方式,主要是通过实践,其次是要有意识地构造。关于这个观点,话题太大,我不打算赘述。

3.虽然技术路线的选择不是核心竞争力,也不应该具有决定性,但对于个人职业路线还是具有比较重要的影响力。但这并不是说,我们应该煞有介事地把自己归于Java或者.NET技术阵营,整天捧本书吭哧吭哧啃。正确的态度应该是着重于你要干的事情,然后认真把这件事情做好,通过必要的学习将所需的知识体系构筑完整,在整个过程中及时更新知识体系。只有心理没谱的人,才会为新技术的推出感到惶恐,因为他不知道自己要干什么,也就不知道自己要学什么,看到什么东西出来了都以为如果不学就会落伍,才会觉得是个压力,日积月累,才会痛苦彷徨嚷嚷怎么办。相反,如果你很清楚地知道自己要做什么,就会发现,其实必须及时更新的知识变化并不频繁,大多数新鲜玩意根本不在自己关注范围内,任他三仙落地,五佛升天,与我何干?因此完全可以安步当车,稳扎稳打。

4.几年前我刚加入CSDN的时候,.NET和Java之争是最热门的话题。现在回过头看,其实当时无论你选择那条路,如果认真做下去,搞些实事,别玩虚活的话,现在都应该有成就了。当然,客观上来说,这几年微软技术变化是比较快,弯弯绕得比较多,相比之下,如果当时你选择的是Java,可能这几年过的比较幸福一些,这是事实。我对此并不是没有自己的看法,但是这毕竟不是多么大的问题,实际上Java这几年折腾得也够猛,只不过作为一个比较开放的领域,Java为其追随者保留了更多的自由度,而微软的追随者大多数有一种被驱赶的感觉而已。话说回来, 微软的技术变革并不是没有章法的,其今天的技术架构,早在2003年就已经明明白白地公诸于众,只不过因为某些微妙的原因,一些微软跟随者这几年被带着兜了一些圈子,浪费了一些精力,比较辛苦。不过,现在.NET技术体系的尘埃基本落定,从体系结构上看,相对稳定的时期已经到来,投资微软技术可以放心。

5.不过我相信未来不同技术流的应用领域会出现一些明显的分化。在中国,涉及国防、国家安全、命脉产业和关键行业的服务端要害系统,国产化改造是阻挡不住的潮流,长期来看,开源和Java将在这个领域占据主导低位。其他的领域,随着微软技术变革的的大势确定,相信微软的优势不可小觑。这里没有考虑中国政府可能做出的产业调整政策。这次微软黑屏事件,无论是否出于微软本意,其最大的效果在于向有关部门展示了一下其信息战力,中国政军内部有关机构对此不可能不加以警惕,这是否会引起中国国内IT产业政策的调整,现在还不得而知。但我相信,微软系统恐怕将在不长的时间里与中国关键要害领域的核心系统彻底说拜拜。未来中国IT系统的格局,很有可能是居庙堂之高则清一色Linux/Java,处江湖之远则Windows占主导。

6.几年前还有一个热烈争论,就是Java和C#之争。现在实际上尘埃已经落定,两个语言的定位已经分道扬镳。Java实际上已经落实了成为系统语言的诺言,在现在的计算机体系结构上,Java与15年前的C一样,可以成为构造基础设施的利器,而且其性能相当不错,完全突破了之前人们对虚拟机语言的认识局限性。我相信在未来,Java将有效地侵蚀C语言的一些曾经以为千秋万代永不变色的地盘。虽然同时Java也在向上发展,但是其力度与C#不可同日而语。相反,C#主要是在往上发展,即将成为超级瑞士军刀,微软版十全大补膏,所有于应用开发有意义的特性都要加上,从编程语言发展来看,它将成为一株奇葩。作为一个编程语言的爱好者,我正饶有兴致地注视着史上特性最丰富语言C#的发展动向。但是,不得不指出,C#的弱点在脚跟。自从用它开发Longhorn Avalon失败以后,微软暂时放弃了让C#成为系统语言的努力,专心专意让C#变成应用开发领域的超级无敌霸王3000,而在核心领域,仍然是C++、COM当关。这就出现了有趣的局面,在可见的未来,微软体系内真正的核心软件基础设施,还是将由微软自己用C++来构造,而组合装配的应用开发,则由C#完成。VB和CLR平台上的其他动态语言都不会有太多机会,因为C#将穷尽神智正常者一切关于语言的幻想。
以上几点,如果有人现在要选择技术路线,可以参考一下。但切记,技术路线的选择重要,但不具有决定意义。

转自孟岩的博客《技术路线的选择重要但不具有决定性》