英语学习网站链接备忘

http://www.youtube.com/user/ValenESL 老师有特色

一些网站,里面有学习相关资源的链接

http://legacy.lclark.edu/~krauss/toppicks/toppicks.html

http://legacy.lclark.edu/~krauss/toppicks/listening.html

http://home.hiroshima-u.ac.jp/flare/EnglishStudySite.html

http://www.betteratenglish.com/video-audio-english-learning-resources/

voa学习英语

http://www.freexinwen.com/chinese/eng/eng.htm

有字幕,难度也不高的一些视频

http://www.breakingnewsenglish.com/

http://www.bbc.co.uk/worldservice/learningenglish/

http://www.voanews.com/learningenglish/home/

http://australianetwork.com/learningenglish/

http://australianetwork.com/livingenglish/default.htm

http://australianetwork.com/businessenglish/default.htm

http://a4esl.org/podcasts/

http://www.englishcentral.com/watch

http://esl-lab.com/

http://www.elllo.org/

http://www.engvid.com/

cnn学生英语,稍难一些

http://edition.cnn.com/video/#/video/education/2012/01/18/sn-0119.cnn

youtube上一些英语学习相关的链接

http://www.youtube.com/user/EnglishCentral

http://www.youtube.com/user/EnglishMeeting

http://www.youtube.com/user/JenniferESL

http://www.youtube.com/user/sozoexchange

http://www.youtube.com/user/EnglishLessons4U

http://www.youtube.com/user/teacherjoedeveto

http://www.youtube.com/user/SeattleLearning

http://www.youtube.com/user/PrivateEnglishPortal

http://www.youtube.com/user/duncaninchina

http://www.youtube.com/user/VOALearningEnglish

http://www.youtube.com/user/madhubkrishnan

http://www.youtube.com/user/podEnglish

http://www.youtube.com/user/bbclearningenglish

http://www.youtube.com/user/EngLanguageClub

http://www.youtube.com/user/BritishCouncilLE?ob=video-mustangbase

http://www.youtube.com/user/KidsOnlineEnglish?ob=video-mustangbase

http://www.youtube.com/user/ENGLISHCLASS101?ob=video-mustangbase

http://www.youtube.com/user/omigrad?ob=video-mustangbase

http://www.youtube.com/user/EnglishcafeDotCom?ob=video-mustangbase

http://www.youtube.com/user/JenniferESL/videos

http://www.youtube.com/user/SeattleLearning?ob=video-mustangbase

http://www.youtube.com/user/TeacherPhilEnglish?ob=video-mustangbase

http://www.youtube.com/user/learnamericanenglish?ob=video-mustangbase

http://www.youtube.com/user/learnexmumbai?ob=video-mustangbase

http://www.youtube.com/user/bizpod?ob=video-mustangbase

http://www.youtube.com/user/JamesESL?ob=video-mustangbase

http://www.youtube.com/user/askmisterduncan?ob=video-mustangbase

http://www.youtube.com/user/SuperSimpleSongs?ob=video-mustangbase

http://www.youtube.com/user/wearebusybeavers?ob=video-mustangbase

http://www.youtube.com/user/EnglishMeeting?ob=video-mustangbase

http://www.youtube.com/user/RebeccaESL?ob=video-mustangbase

http://www.youtube.com/user/hellochannelenglish?ob=video-mustangbase

http://www.youtube.com/user/hotforwords?ob=video-mustangbase

http://www.youtube.com/user/EnglishSocialNetwork?ob=video-mustangbase

http://www.youtube.com/user/khanacademy#p/c/CECDA315A8848B99

youtube上一些公司的官方账号

http://www.youtube.com/user/Apple

http://www.youtube.com/user/CNNInternational/videos

http://www.youtube.com/user/microsoft

http://www.youtube.com/user/google

http://www.youtube.com/user/nbc

npr,比较难,但是都有字幕

http://www.npr.org/

针对12306问题乱弹架构设计

关于12306网站架构,不少人提出了自己的设计思路,有的人很简单,比如说nodejs就行,nosql一定可以,或者是某某方案最适合了。看了不少文章,感觉还是coolshell的最实际靠谱 http://coolshell.cn/articles/6470.html 。由于末学对网站架构方面翻译的文章很少,不敢说自己是大型网站架构师,实战经验更是没有,就不充大头提什么技术方案了,只从比较虚的架构设计方面说说自己的一些见解。

一个实际的不成功例子

最近组内一个内部项目,从设计到实现一起群体智慧完成,但是进度和完成质量却比我想象的差了很多。项目很简单,大概就是一千多条数据,使用Asp.net MVC3搭建。为了技术练手,把后台部分大部分逻辑做成webservice,使用WCF搭建。业务内容也相当简单,不过就是CRUD。因为数据库使用Access(客户决定),所以SQL都是手写,包装成DBHelper给业务使用。就这样一个简单设计,却也经过了两次总体设计,比预期进度慢了很多,完成度和设计优美程度都比预期的差。个人感觉而言,项目不能说失败,但也称不上成功。好在我们当时的想法就是用这个项目来锻炼团队,这样想心里还能好受些。

自我反思,不成功原因很简单,最主要是团队在这方面经验不足造成的(还有其它原因不方便说)。某个人是否能很好地完成一项工作,首要的是态度,其次是能力,所以选择的时候这两方面都需要考虑清楚。另外,对于新人不要设置太高标准,需要适当给以监督和辅导。

从这个实际例子就可以看出来,架构问题不会也不可能是简单的说几句话,指个方向就能完成。再好的纸上谈兵,放在现实中也可能出现预料不到的困难。所以最好的办法是找靠谱的人,最好是有相关经验的靠谱的人,去做靠谱的事;从试错的过程中吸取教训,不断完善架构设计。架构师的工作不仅仅是把简单问题复杂化或者复杂问题简单化,而是根据项目具体需要,以及相关环境约束,平衡取舍得到一个最合适的方案。

12306的问题

由于春节出行需要,在12306上购买了往返车票,在购买春节前车票的时候,遇到了无法登录的问题,大约花了将近两个小时,才登录成功,并且在下订单时也碰到几次问题,但是总体而言,相比去火车站排队还是要轻松很多,另外提前12天购票也让购票更提前了。

没有准确数据,很难估计12306在高峰时的并发和负载到底是什么样的。如同下面报道中的数据一样,不少说法要么不专业,要么有水分,很难让人信服。http://bschool.sohu.com/20120117/n332409067.shtml 另外铁老大的封闭性以及项目本身可能具有的保密性,谁设计实现,花了多少钱,大致架构如何,也都是个迷。

在9月份以后大致有两个并发相关的大事件,一个是京东促销,两次促销两次接近当机,成绩只能说不及格。另外是淘宝还是淘宝商城的双十一促销,没有怎么关注,据说效果还不错。

除了淘宝比较开放一些,架构方面的宣传比较多,京东这个新晋小生一样是对架构讳莫如深,或者从另一个方面说明,刘强东这个人并不怎么重视信息系统建设。

相比这两个事件而言,12306的成绩不算太好,但也不算差,如果我评分,会给一个70分,已经是及格以上。12306的问题不是技术问题,而是人的问题,或者说是一个权势角力的结果。技术选择从来都不是从底层技术人员发起的。

另外有人评论:界面丑,用户体验差。这个真的不是问题。不少微博上叫唤的欢实的,他们自己公司内部系统的界面和用户体验可能会更差,尤其以报销系统或者人事系统更甚。说句实在的,他们连自己boss都说服不了,让他们自己换换这些差系统,还提出这个那个方面,实在是没有说服力啊。

架构再好,也要团队,软件开发的关键是人

有不少人一说高负载分布式,动辄就是什么nodejs,nosql,缓存,文件系统,大数据这些关键词,好像这些关键词一说,问题立马就解决了。问题在于,这些关键词只是一些点,架构设计和实现其实是一个面或者是立体的。

举一个简单的例子,一个团队,其中的成员大部分是dotnet背景或者是java背景,他们熟悉的是sqlserver或者是oracle,了解的是项目中用到的那些技术,超出这个范围的,不知道不了解都是理所应当的。这样一个团队,如果某个架构师听说nodejs或者nosql可以解决他们的问题,边学边做,照猫画虎,摸着石头过河。你觉得这样的项目会成功吗?!

所以,只有团队整体素质够高,才能够产生一个比较完美的解决方案。这样的团队,只能是有腔调的技术带头人加上比较靠谱的执行者才行。

合适的架构是磨出来的,没有一开始完美无瑕的方案

@fire9 在微博上说好的架构不是设计出来的,而是运维出来的,我对运维这个方向了解很少,对此不评论。我的观点是合适架构是磨出来的,需要一个持之以恒,反复迭代的过程,在某个阶段,也许还需要涅磐重生,关于这个观点,在《The Pragmatic Programmer: From Journeyman to Master》书里就有一个完美草地的例子。

架构设计必须满足几个条件,一个是满足客户需求,在微博上不少人提出种种解决方案,但是越看越像是在炫技,是他们自己有这方面的需要和想法,与客户需求没有一毛钱关系。合适的架构也要获得高层的支持和投入,这一点在中国尤其重要。还有一点,合适的架构要考虑到执行效果,仅仅设计出来,无法实现也是不行的。好的架构师必须保证控制自己的欲望,不要什么技术都往上堆,什么需求都想满足,否则项目的结果只能是失控。

如何磨一个架构?我的经验不多,简单说一些务虚的内容。首先是态度积极,真心想把事情做好,而不是凑付。另外要保证项目的长期性,让团队有归属感。技术上保证不断学习,整个团队一直保持上升势头。另外是团队搭配合理,主力程序员,程序员,项目经理搭配工作,没有很明显的短板。有了这些软件支持,磨出一个好架构不是难事。

方案是经验的体现

回到12306的设计方案可以看出,云风的方案有点类似网游服务器,酷壳陈皓在服务器开发和Amazon积累的经验,让他能够介绍一些关于业务上的问题。 他们以往的经验很好的反映在设计方案中。

如果真的要设计方案,谷歌百度腾讯这些公司里面的大规模并发/大数据/高可用性这些方面的专家很有帮助,但我更相信,来自淘宝Amazon这样电商公司的经验更准确有力,因为他们对业务更熟悉,对于业务流程设计中可能有的风险问题会有更好的体会。技术必须契合业务,才能发挥正面作用。任何时候都不应该是先提技术后谈需求,可惜这样本末倒置的事情经常发生。

12306该怎么做,这个其实不是问题,因为铁道部根本没有问过这个问题,就如同给京东提建议给支付宝提建议无人响应一样,都不过是技术人手痒产生的意淫罢了。不过这些讨论还是可以看出很多闪光点,让我们在以后的设计中采用或者注意类似的方案。

如何开发高质量软件?及软件测试观点

也许是因为我经常在twitter上鼓吹“代码质量来自code review和单元测试”,老赵的这篇文字 http://blog.zhaojie.me/2012/01/a-case-requirement-to-practice-unit-testing-or-tdd.html 也at我一下,抱歉的是最近欠债太多,正在着手完成答应侯伯薇的那篇关于appengine的文字。

趁着兴头和最近的一些工作简单谈谈我的软件测试观点。

上周五小组对前一阵的一个项目做了整体的代码review,然后对单元测试代码也简单review了一下,大概二十几个测试用例完全通过,mstest中一条条绿杠杠让人很开心。

今天英语加技术学习,看了这篇 http://net.tutsplus.com/tutorials/ruby/the-intro-to-rails-screencast-i-wish-i-had/ 其中正好讲解了如何使用TDD开发rails程序,酷毙了,其中guard,rspec,capybara这些Ruby的好玩意让我等DotNet程序员羡慕不已。

如何进行高质量软件开发?是我这大半年一直在思考和研究的问题。对于我们大部分项目的流程,简单总结起来就是,前期需求review,设计review,风险评估,开发中期review,代码结束review,维护阶段。

前期review主要是保证项目不要过早的投入编码,设计上不够成熟或者没有考虑的很清晰。我发现不少人是以编码代替设计,或者说还没有想好怎么设计,代码就号称写完百分之八十了,很无语。前期review以主力程序员担当设计和主要技术攻关,并且反复确认设计中不清晰的地方。在前期设计阶段也会对任务进行分派,其中有程序实现,单元测试实现,手动测试实现,代码review等不同角色。理论上说单元测试应该由程序实现者完成,但是由于项目特点决定,我们对于某些项目的单元测试是有另外的程序员实现,稍大一些的项目(或者说story)就需要有三个人熟悉设计和代码实现,大致是一到两个实现者,一到两个代码review人员,这样有些人担心的“对项目不熟悉代码不熟悉,怎么进行code review?“的问题就不存在了,而且也很好的保证了万一有人请假有事,其他人也可以很快完成任务。

开发中期review,主要是对整体思路再次检查一遍,另外确保项目整体质量是OK的,上个月就在中期review的时候,果断叫停某个质量很低的项目,调入一个主力程序员重新设计,虽然浪费了一些时间,但是代码质量比前一个版本要好很多。

代码结束review,是整个小组对项目实现进行逐行的分析解读,貌似这样会比较浪费时间。但是我们现在团队初建,很多技术甚至是常识都需要反复强调,这种小组review很有必要,也是很好的学习过程。

再着重谈谈单元测试。通过比较NUnit和MSTest后选择MSTest作为测试框架,另外也会选择集成测试或者是接口测试等不同测试级别,主要是看项目需要,并不拘泥于非要单元测试。现在的问题是单元测试本身设计的还不够,基本上只考虑”正常、异常、上临界、下临界、空值、复杂值“这些情况,没法做到很好的代码覆盖率,希望这个在以后能慢慢提高。MSTest的使用很简单,基本上跟Nunit没啥区别,好处是可以直接集成在VS2010高级版中,另外也可以通过mstest命令行调用,持续集成也很容易。

我们基本上会在项目设计阶段就对测试用例同时进行设计考虑,然后会留出大约百分之三十到四十的时间给单元测试或者自动测试。这个比例根据项目重要程度或者复杂程度也会相应地调整。

另外一个很关键的问题是”如何测试GUI?”对于asp.net mvc,我们基本上只会自动测试controller,对于view部分,是准备使用自动的browser测试框架来做,现在还是以手动测试为主;对于wpf程序,主要是测试viewmodel部分,但是现在也主要以手动测试为主。对于需求倾向于前端的应用,基本上不会考虑单元测试。但是为了很好地保证质量,我们会把关键的需求点作为测试用例,然后有人专门做手动测试。也开发了一个自动记录回放的小软件,但是效果一般,基本没用。

团队初建,我个人经验不足,所以很多也是在摸索调整,希望以后能有更完整高效的开发流程可以分享给各位。

为何node.js需要coroutine【转】

转自 http://shiningray.cn/node-js-coroutine.html

这篇文字以前看到时候印象不错,但是没有体会,最近重新阅读,觉得非常棒,转一下。

=================

这其实就是我关心为何node.js需要coroutine。

很多语言,像Java C/C++,虽然要深入了解他们,很复杂,但一个应用可以由资深的程序员,写出一个框架,然后通过框架隐藏那些复杂的细节,然后由其他初级程序员来编程实际的复杂应用逻辑。现在很多外包公司就是这样,甚至是由主程序员写一个代码模板,然后让其他小弟们来改改。

Python、Ruby就在这上面更进一步,不仅可以开发一个框架,还能设计一种DSL,让逻辑的编写更加简单。

但是node.js虽然隐藏了event-loop和async io的细节,但是却把异步处理的流程控制的问题丢给了开发人员。即使是上层负责逻辑的程序员,也常常被异步所干扰。

计算机本身其实多个不同的设备之间进行通信,必须要考虑很多同步的问题。冯诺依曼机的理念就是把一些同步发生的东西,通过时钟进行同步,让本来必须考虑并行的编程,简化为了串行编程,然后我们就可以使用简单的流程图了。这是冯诺依曼机最大的贡献。

很多时候,对于编程中的某个连续的逻辑来说,我其实并不关心读取文件是阻塞还是异步,请求数据库要考虑超时什么的。我的目的其实很简单,就是读取文件,获得内容,然后放入数据库等等。

而现在node.js的做法似乎就是抛弃了这种模式,但是node.js却无法实现真正的并行编程,比如利用多核,这是很奇怪的事情。


然而如果有了coroutine,那么我们可以设计出一个框架,在框架之上,普通程序员还可以继续按照以前的方式来写代码,像底层的异步操作则应该是资深程序员关心的事情。

比如,一个从a文件读取内容,然后写入b文件的一个代码:

这个是node.js的代码

fs.readFile('a.txt', function(err, data) {
  if(err){throw err;}
  fs.writeFile('b.txt', data, function(err){
    if(err){throw err;}
  });
});

而传统方式的伪代码如下:

try{
var data = fs.readFile('a.txt');
fs.writeFile('b.txt', data);
}catch(err){}

很明显是传统方式的伪代码更加清晰,node.js使用的CPS给人感觉非常冗长。如果有coroutine,那么node.js还可以进一步把核心库中的*Sync版本给删减。

那么有了Coroutine的话,我们可以给原先的代码改成这样

function readFileSync(file){
   var co=Coroutine.current();
   fs.readFile(file, function(err, data){
     co.resume(data); //1
   });
   return Coroutine.yield(); //2
}
var data = readFileSync('a.txt')

这段代码使用当前的coroutine来等待io操作,会在(2)处挂起当前coroutine,等待唤醒,当异步i/o执行完成以后,则在回调函数的(1)处唤醒当前的协程。

当然这样写的话会阻塞当前的协程,如果要不阻塞当前的协程,我们可以这样写:

var co = Coroutine.create(function(){
   var data=readFileSync('a.txt');
   writeFileSync('b.txt', data);
});
co.resume();

这样创建一个新的协程把任务单独隔离开来,至于你什么时候需要调用该协程,则由自己安排。

这样使用Coroutine的好处是,你可以对自己的每一个请求进行概念抽象,把每个请求封装成coroutine,那么在这种请求中的处理逻辑还是可以按照原来的方式去编写。

有些人可能认为coroutine太浪费内存,但据目前很多coroutine在高并发程序中的应用来看,是可以接受的;而回调模型要引入大量的函数对象以及大量闭包,未必就能更省内存。

另外还有人提到Coroutine也可能会出现一些同步问题,但这并不能成为不使用Coroutine的理由,写的不好的回调机制一样也会产生同步问题。


实际的应用可能更加复杂,举个例子。在糗事百科的web端,常常要先从memcached中获取缓存,如果缓存不存在,则读取数据库,然后再把内容存入memcached中。这是个很常用的逻辑。来段同步版伪代码
var data = Memcache.get('key');
if(!data){
  data = Mysql.execute(sql);
  Memcache.set('key', data);
}
//后面的代码

当然这里也不考虑什么竞争条件什么的问题了。
如果是node.js,那么则变成了

function rest(data){
  //后面的代码
}
Memcache.get('key', function(err, data){
   if(data){
     rest(data);
   }else{
     Mysql.execute(sql, function(err, data){
        Memcache.set('key', data);
        rest(data);
     });
   }
});

本来很清晰的代码,却被回调函数弄得支离破碎,即使使用一些像Step/Do这些DSL来协助,还是不如原来的更加直观。


综上所述,node.js的特点是易于上手,容易编写,同时性能还不差,但问题在于,到了一定复杂程度之后,代码编写就比较困难了,不容易构建较复杂的应用,所以引入Coroutine才可以让node.js真正进入大型应用的领域。

PS,其实有call/cc也可以解决很多问题。

Python使用微软Access

PyODBC是一个很好的软件,可以用来连接使用微软Access数据库,http://code.google.com/p/pyodbc/

快速示例在这里 http://code.google.com/p/pyodbc/wiki/GettingStarted

也可以使用PyWin32COM来连接ODBC。

可以用这个模块来方便访问 http://pypi.python.org/pypi/execsql/0.4.4.0

这个工作主要用在一个数据库迁移的小项目上。

Sqlite与Access互相转换的一个软件,不知是否可用

http://sqlite.awardspace.info/syntax/sqliteodbc.htm

在Sqlite中建立Access数据库

http://code.activestate.com/recipes/572165-recreate-ms-access-table-in-sqlite/