2012年5月11日星期五

关于技术的学习方法

关于学习,时间短与效果好始终是一对矛盾的统一体。

很多时候,要想在最短的时间内完成一件事情,最好的方法就是依葫芦画瓢,但这样的话,即使完成了事情,也只是知其然而不知其所以然,长久来看,对于学习者的能力不会有多大的提高。

从长远来看,要想自己基础扎实,能力强,那就得一步一步的来,从基础知识开始,一点一点的搞懂,但这种方式需要花费很多时间,短时间内效果不明显。而且,可能效果没有预期的那么好。

那么,如果做个权衡呢?

我想,也许最好的学习方式是:先依葫芦画瓢地实践,获得一些直观感受,最好还有一些疑问。在实践完成之后,在整理自己的疑问,以及实践中涉及的知识要点,通过查阅图书或者网络资料,逐个知识点巩固,逐个解决疑问,并整理成文。这个整理总结的过程可能需要较长的时间。

这种方式的优势在于:1.能让你快速地完成事情;2.实践中用到的知识多半会在以后的实践中经常用到,掌握的就是一些最重要的东西,而不会学习一些很少使用的深奥偏门知识。

2012年5月7日星期一

给自己的几点编码建议

  1. 注意命名方式,需统一
  2. 多写良好的注释
  3. 内嵌文档注释,并利用文档自动生成工具产生项目文档
  4. 常重构,精益求精。

2012年4月20日星期五

关于指针的一道笔试题

同学找实习,遇到这样一道笔试题:
int *a[2][3];
sizeof(a) = ?
sizeof(*a) = ?
sizeof(**a) = ?
sizeof(***a) = ? 
这题还是有点小意思的。遇到这种题,脑子一定要清楚,注意分析。

对于int *a[2][3]应该这么理解:
a是个数组,有两个元素;元素也是数组,其有3个元素,每个元素是指向int类型的指针。
指针的长度固定为4个字节,C语言的int类型也是4个字节。

这样一分析,这题就简单了。
  • sizeof(a)意思是求a数组的长度,数组的长度=数组元素的个数*元素的长度,所以sizeof(a) = 2 * 3 * 4 = 24个字节
  • sizeof(*a)中的*a是指a的第一个元素,所以sizeof(*a)就是求a数组的第一个元素的长度,即sizeof(*a) = 3 * 4 = 12个字节
  • sizeof(**a)则是求a的第一个元素(也是数组)的第一个元素(是指向int类型的指针)的长度,所以sizeof(**a) = 4个字节(即为一个指针的长度)
  • sizeof(***a),因为**a是一个指针类型,那么***a即为*(**a),那为指针指向的值,这里为int类型,所以sizeof(***a) = 4个字节(int类型的长度)

2012年3月31日星期六

学习的"道"与"术"

读研以来,一直觉得自己的学习方法不够高效。试图将要学习的东西进行分类,然后以不同的方法学习之。那么该如何分类呢?我觉得以"道"与"术"区分之比较合适。


何为“道”?汉语辞典中有两条解释:1.指法则、规律;2.学术或宗教的思想体系
何为“术”?:技艺


字面理解,“术”更为具体,是完成一件事情的具体过程。而“道”者则是指导实践的思想,是能够举一反三的事物规律。

那么是否“道”比“术”更重要呢?我想未必。任何理论,任何“道”都最终来源于“术”的实践过程,也最终需要在“术”上得到实施,才能体现其价值。“道”与“术”两者相辅相成。那么在我们学习一门学问的过程中,就存在一个“道”与“术”何者为先的问题,即从“道”还是“术”入手学习?

孟岩说过这么一段话:
我主张,在具备基础之后,学习任何新东西,都要抓住主线,突出重点。对于关键理论的学习,要集中精力,速战速决。而旁枝末节和非本质性的知识内容,完全可以留给实践去零敲碎打。
原因是这样的,任何一个高级的知识内容,其中都只有一小部分是有思想创新、有重大影响的,而其它很多东西都是琐碎的、非本质的。因此,集中学习时必须把握住真正重要那部分,把其它东西留给实践。对于重点知识,只有集中学习其理论,才能确保体系性连贯性、正确性,而对于那些旁枝末节,只有边干边学能够让你了解它们的真实价值是大是小,才能让你留下更生动的印象。如果你把精力用错了地方,比如用集中大块的时间来学习那些本来只需要查查手册就可以明白的小技巧,而对于真正重要的、思想性东西放在平时零敲碎打,那么肯定是事倍功半,甚至适得其反。
虽然这段话并没有明确区分学习的“道”与“术”,以及何者为先的问题。但却大致说明了何为正确的学习方法。


从“道”与“术”的角度来理解,那关键的,核心的,创新的部分即为“道”,“大道”。而那细节的则是“术”的部分,是需要长时间的实践的,也许只有在实践中遇到的细节才是有意义的。


但那“具备基础之后”的“基础”是什么呢?我想应该是:1.明确问题是什么。这一点是再怎么强调都不为过的。要解决一个问题却没有真正明确问题到底是什么,那你努力多半是白费的。2.这东西是用来干什么用的,是用来解决什么问题的?对于工科学生来说,学习新东西的时候,这一点是需要首先明确的,只有明确了“干什么用的”,才能抓住学习的重点,提高学习的效率。3. 与以前的类似的东西相比,其区别是什么?一样东西,一种理论其价值往往在于对前人的突破,这突破的地方才是我们真正要掌握的。在学习一样东西之前,不妨多问问自己为什么要学这个,这东西对自己有多大的提升?不断地重复学习类似的东西,多半是没有意义的。


具备了基础之后,对于关键理论的学习,是不是只要抱着书本,理论对理论的学习就行呢?我想这是万万不可的。特别是对于着重于实践性的学问,比如编程,理论对理论地学习,只会让你吃力不讨好。绝大多数的创新理论,核心理论,都不是一下子就能理解的,特别是当你对这一领域的学问并不熟悉的情况下,它需要在反复的实践中逐步地加深理解。


那么对于关键内容的学习,我觉得这样学习会比较合适:先快速地,在尽可能短的时间内把关键内容浑沦吞枣地过一遍,能理解多少是多少,目的是为了获得一个理论的一个Big Picture,明确理论的各个部分之间的大致关系。然后对于每个部分,以及部分之间的关系,逐个地通过实践来验证你的理解,但这个实践过程并不属于“术”,因为它不是为了技艺,而只是为了验证自己对理论的理解。这一验证过程结束之后,你应该就能够对关键理论有个整体的正确的理解了。


然后,你就放开手去干吧,去解决那些现实中的问题!


也许,你会说,不用这么复杂吧?是的,如果你只是为了解决一个实际的问题,而这个问题也存在相近的解决方案,你不想也不需要弄懂这个问题,好吧,那你就直接去找解决方案吧。但你解决这个问题之后,你学到了什么呢?当你再次遇到一个本质上一样的问题的时候,你还是能快速地解决么?没有真正弄懂问题,没有弄懂问题背后的知识,那你就准备着为类似的问题重复地去寻找解决方案吧。恩,看起来有点傻哦。

2012年2月21日星期二

Python学习路线(针对具备一定编程经验者)

相比C,C++,JAVA等编程语言,P​ython​是易学的。但要想深入地理解​Python,并熟练地编写Python风格的Python代码。我想还是有一长段路程要走的。下面即是我的一点经验总结,主要是为了整理自己学习的思路。


1. 花1-2天的时间阅读一本好的Python入门书籍,并在亲手实践书中的代码。推荐入门书籍:《A byte of Python》(中文翻译《简明Python教程》)或《Practical Programming:An Introduction to Computer Science Using Python》(中文翻译《Python实践教程》)或者其他的比较薄的入门书籍。


2. 抛开书籍,用Python去写一切你想写的程序。这时最好的参考文档即为:1.Python命令解释器中的help(),dir()辅助方法;2.Python官网文档:http://docs.python.org/ 。遇到不清楚的地方就用这两个方法查,再不行就去google一下。


3. 两三个月之后,积累一点的代码量,再重新找本讲解比较详细的书,重新梳理一下自己对Python的理解,纠正自己实践中一些不好的方式。推荐书籍:《Beginning Python: From Novice to Professional》(中文翻译《Python基础教程》),《Learning Python》(中文翻译《Python学习手册》),《Dive into Python》,《Core Python Programming》等。另外,也应该在编码的过程中重复地去查阅Python标准函数库,标准库里已有模块实现的功能就不要自己实现。


4. 之后,根据实际需要,去了解使用一下Python的各个方面的函数库(比如http://docs.python.org/modindex.html中罗列出来的,以及matplotlib, numpy等用于科学计算,图形图像处理的),特别是诸多的Web框架(django, web2py, cherrypy, tornado等),可以先从简单的开始。如果是对Python的底层实现感兴趣,那么就该去看看Python源码,阅读一下《Python源码剖析》; 如果对文本处理感兴趣,可以阅读一下《Text processing in Python》等; 如果对网络感兴趣,可以阅读《Foundations of Python Network Programming》,尝试实现一个简单的web server ...


5. Python相关的开源函数库非常非常的多,各个方面的都有,所以学习者应该尝试着去用它们,了解它们,而不是啥都要自己来实现。因为Python擅长的就是快速开发,而且站在前人的肩膀上,我们才能站得更高,看得更远。当然如果你想加深自己对某个方面的理解,也可以尝试去实现一些简单的模块。


6. 总之一句话:学习Python的关键就是用!而且是要多用别人的。动手实践才是王道!那么多优秀的开源函数库不要浪费了!

2012年2月16日星期四

VNC简介

VNC(Vitual Network Computing) is a graphical desktop sharing system that uses the RFB protocol to remotely control another computer. It transmits the keyboard and mouse events from on computer to another, relaying the graphical screen updates back in the other direction, over a network.

VNC is platform-independent --- a VNC viewer on one operating system may connect to a VNC server on the same or any other operating system. There are clients and servers for many GUI-based operating system and for Java. Multiple clients may connect to a VNC server at the same time. Popular uses for this technology include remote technical support and accessing files on one's work computer from one's home computer, or vice versa.

A VNC system consists of a client, a server, and a communication protocol:

  • The VNC server is the program on the machine that shares its screen. The server passively allows the client to take control of it.
  • The VNC client(or viewer) is the program that watches, controls, and interacts with the server. The client controls the server.
  • The VNC protocol(RFB) is very simple, based on one graphic primitive from server to client("Put a rectangle of pixel data at the specified X,Y position") and event messages from client to server.
By default, RFB is not a secure protocol. While passwords are not sent in plain-text(as in telnet), cracking could prove successful if both the encryption key and encoded password are sniffed from a network. For this reason it is recommended that a password of at least 8 characters be used.

由于VNC系统是服务器-客户端模式的,所以先得在服务器(被控制的一方)上装上VNCserver,然后在客户端(主动控制的一方)上装上client(VNCviewer)。按照vncserver --help说明启动vncserver。服务器端有三个命令可以使用:vncconfig---配置命令,vncpasswd---设置client连接到服务器时需要的密码,vncserver启动一个server进程(对应一个Display No.),监听端口。

在服务器端的/root目录下会有个隐藏的文件夹.vnc,里面有加密过的密码文件passwd,每个vncserver进程的日志文件,以及配置文件xstartup。

服务器端启动vncserver后,即可在客户端启动vncviewer,在server一项中输入服务器的ip,后面跟一个:,以及一个Display No.,如果服务器端只启动了一个vncserver进程,那么就是1。然后直接回车,出现需要输入密码的登录框,输入服务器端设置的密码,然后直接回车即可。

2012年2月15日星期三

Linux命令习题


For each of the outputs listed below, find one sequence of commands connected by pipes that produces the output. For each problem, turn in the command sequence that you used to generate the requested output. (Do NOT turn in the output itself.)

1. A listing of all processes that you are currently running on the machine you are using, sorted by the command name in alphabetical order (i.e. a process running acroread should be listed before a process running bash). The output should consist only of the processes you are running, and nothing else (i.e. if you are running 6 processes, the output should only have 6 lines). 
ps -e --sort cmd
2. The number of words in the file /usr/share/dict/words (*) which start with the letter a.
[* Note: On some Unix/Linux systems, the dictionary has the filename /usr/dict/words]
cat /usr/share/words | grep ^a.* | wc -l
3. A "long" listing of the smallest 5 files in the /etc directory whose name contains the string ".conf", sorted by increasing file size. 
ls -lSrp | grep [^/]$ | grep [\.]conf$ | head -n 5
4. An executable file, named "echo.sh", with one sequence of commands to print hello world! on screen. 
(1) vim echo.sh and the content of echo.sh is echo hello,world! 
(2) chmod +x echo.sh
(3) ./echo.sh