- 浏览: 282594 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (234)
- php (70)
- linux (46)
- apache (9)
- mysql (13)
- oauth (1)
- IT新闻 (18)
- 代码收藏 (20)
- python (2)
- webservice (6)
- 评论 (7)
- asd (0)
- 开源软件 (6)
- 前端 (9)
- 7z (1)
- js (17)
- windows (4)
- cmd (2)
- 开源 (3)
- vim (6)
- windows 软件安装错误 (2)
- 分享 (3)
- search (1)
- node.js (1)
- xmind (1)
- 变成语言 (1)
- drupal (0)
- jquery (2)
- css (7)
- ietester (1)
- 编辑器 (1)
- java (2)
- html5 (1)
- 生活 (1)
- Sublime Text 2 (1)
- 制图 (0)
- sublime (1)
最新评论
-
muxueqz:
我自己写了个开源的:http://muxueqz.top/sk ...
Delicious被Yahoo卖了 -
yangyongnihao:
...
REST与SOAP样式Web 服务的区别 -
wangshaofei:
zhou7707 写道 大神啊,太及时了,我今天服务器上不了 ...
Debian 6 下搭建nginx 1.3 -
zhou7707:
大神啊,太及时了,我今天服务器上不了外网,为搞包依赖折腾一 ...
Debian 6 下搭建nginx 1.3 -
wangshaofei:
bbs_ld 写道一楼说的对啊。如何解决呢?? 高手大人
利用php创建日期选择框
酷壳 - CoolShell.cn
More like this...
If you'd like to automatically receive updates to this feed, you can subscribe now.
这是个StackOverflow上的问题 How can you program if you’re blind? 。在看到这个问题的时候,我感到应该不可能,但是我错了,这个问题的前两个答案让我深深地震憾了。
第一个答案的回复人是Jared(其在StackOverflow上的积分有将近14K),但是你能想得到他是一个盲人吗?他回复到——
我是一个完全失明的大学学生,我做过一些程序员的实习工作,所以我的回复基于我的这些经历。我使用Windows XP 和 Jaws 来为了读出屏幕上的内容。
对于Java 编程,我使用eclipse这个强大的IDE。我使用SWT开发GUI。对于.NET编程,其使用Visual Studio 2005,使用Jaws可以非常容易地操作VS2005,而且其还有一些很不错的脚本来可容易地用来做表单设计。
对于C/C++,我使用cygwin + gcc 也使用emacs 和 vim 做出编辑器(使用Emacspeak虽然有时候有点迟钝)。在实习过程中,我做了很多和Z/OS相关的编程工作。我使用rlogin通过cygwin登录大型机的USS系统,并使用C3270作为其3270仿真器来访问大型机的ISPF部分。
我依赖于合成语音系统,也需要 Braille display, 我发现使用合成语音系统很快,但是使用 Braille display有时候有些问题。比如程序有太多的嵌套括号。
关于Braille display,又叫盲文显示机,是能以盲文进行输出的电子机械式设备。一般来说,该设备通过在平坦表面上打孔来实现点阵的表现。有了该设备的帮助,无法使用一般的显示设备的失明用户也能够阅读文字。如下所示。
第二个答案是Saqib提供的,其个人主页是http://www.saqibshaikh.com/,目前在Microsoft的Bing项目组,他回答到:
我是盲人,我对Windows, Mac, Linux 和 DOS有13年的编程经验了,我会的编程语言是C/C++, Python, Java, C#或是其它相似的语言,虽然问题问的是怎么来设置盲人的环境,但是我想从盲人怎么使用电脑来回答。
有些人使用“语音环境”,如T. V. Raman程序员和Emacspeak 环境。这样的环境需要有读屏程序来监控操作系统的行为,并通过合成语音系统或是Braille display 来告诉盲人屏幕上有什么。这样一样,盲人就可以操作任何的应用程序了。
我个人这段时候使用Visual Studio 2008(注:作者是09年回的这个贴的),用其来做一些修改。我关闭了一些VS2008的功能,如显示错误,因为这会让我分心。在加入微软以前,我都是在用notepad这样的东西开发程序。
对于读屏软件,我需要设置一下,以便其告诉我缩进。老实说我不太关心这个事,因为VS2008对程序缩进做得很好。但是对于Python来说,这个功能相当重要。最终,Emacspeak 可以使用不同的声音来让我区分缩进的语句块,以及一些语法(关键词,注释,标识,等等。)
对于Saqib,大家有兴趣可以看看他的视频访谈:Saqib Shaikh and Scott Hanselman: Designing for Accessibility
这个问题中多次提到了Google的盲人程序员 T.V. Raman,我在网上搜了一下他,他前段时间来过北京,新京报在今年早期报道过他——《T.V 拉蒙,互联网界也有“盲剑客” ——Google盲人工程师讲述软件设计之路》
在这篇报道中,他经历过IBM, Adobe和Google 这三个公司,他可以在23秒内复原盲人魔方,1989年他就得到一台给盲人用的语音合成器和当时最先进的读屏软件。他现在使用电脑 没有任何障碍,他天天都上网浏览信息,他还可以使用特别的手机来看地图。
不知道你看完这些人的经历后,你有什么感觉?
- 你是否会觉得技术的力量和社会的尊重让他们和正常人一样可以使用电脑?
- 你是否会觉得我们这些正常人是不是平时抱怨的太多了呢?还有什么理由不努力的呢?
相关文章
- 2011年09月08日 -- 千万不要把 bool 设计成函数参数
- 2011年08月26日 -- C语言中史上最愚蠢的Bug
- 2011年08月23日 -- 弱爆程序员的特征值
- 2011年08月16日 -- 重构代码的7个阶段
- 2011年08月01日 -- 你确信你了解时间吗?
- 2011年07月18日 -- 程序员技术练级攻略
- 2011年07月12日 -- 给程序员新手的一些建议
下面是近期收录的一些文章和资源,希望对你有用。
系统方面
- 印度的电子商务网站flipkart的性能扩展(PPT) http://www.slideshare.net/sids/how-flipkart-scales-php,都是一些最基本的东西,对于初学者来说很不错。PPT做的也不错。
- Tagged.com的扩展之路 – 1亿用户,1000台服务器,50亿的PV http://highscalability.com/blog/2011/8/8/tagged-architecture-scaling-to-100-million-users-1000-server.html 还是PHP的WEB站点。另外,highscalability.com这个网站上有很多和高性能有关的文章,很不错。比如最新的:Stuff The Internet Says On Scalability For September 16, 2011
- 浏览器是怎么工作的? http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/ 相当不错的一个教程,告诉你浏览器里面是怎么搞的,很不错。如果图片看不到,可以看这里。如果你英文不是太好,你可以看看中译版,译得并不是太好。
Mozilla's Gecko rendering engine main flow
- Intel C/C++ 64位程序开发教程 http://software.intel.com/en-us/articles/lessons-on-development-of-64-bit-cc-applications/ 本站以前也介绍过一个关于64位C/C++的编程注意事项。
各种教程
-
- Version Control by Example(电子书) http://www.ericsink.com/vcbe/
-
SQL注入口袋书(Google Doc 需fanqiang),涵盖MySQL, MSSQL和Oracle,我觉得可以用来做你的程序的安全测试。
- 如何写Vim的插件(教程)http://stevelosh.com/blog/2011/09/writing-vim-plugins/ 相信你已读过“VIM简明攻略” 并收藏了 “vim的速查卡”,随着你的vim的能力加强,是时候搞搞vim的插件了。
- 一个超有意思的学习Javascript的在线课件了。下面的这个网页上有一个Web的命令行,你可以跟着他的提示去输入一些命令,并以此来学习Javascript,这个创意真是太好了,我觉得这应该推广到我们的学校中去,不是只听老师讲,还需要大家一起来动作。http://www.codecademy.com/
- 一些各种各样的教程 http://www.dickbaldwin.com/toc.htm 这些都是些入门的教程,仅当是练练英语了。
Web库
- 20 个 jQuery提示插件:http://zoomzum.com/jquery-tooltip-plugins/
- 最近出的一个新的可以做Web幻灯片的Javscript http://imakewebthings.github.com/deck.js/#intro 当然,Web上做幻灯片的库太多了,大家可以看看wikipedia上的一个收集: http://en.wikipedia.org/wiki/Web-based_slideshow
-
Google APIs Client Library for PHP - 用PHP封装的各种Google API
- Django Google Chart http://publishedin.com/django-google-charts/ 为Django封闭的Google 统计图API。
- 一个新的HTML5+CSS3的JS库Kendo UI:http://demos.kendoui.com/ 这样的JS库有很多,如比较经典的ExtJS, YUI 和 jQuery。不过大家可以试试这个库。其支持移动设备。
HTML 5
- HTML5 Canvas 的开发指导:http://www.sitepoint.com/a-developer%E2%80%99s-guide-to-html5-canvas/
- HTML5+ Javascript的游戏开发教程:http://gamedev.slashgame.net/2011/08/html5-game-development-tutorial.html
- 70 个 HTML5 的精彩示例 http://www.instantshift.com/2011/07/05/70-inspirational-examples-of-websites-designed-with-html5/
编程规范
- The Art of Assembly Language Programming 汇编语言艺术 http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/toc.html
- 编程规范 if语句的简单规则:http://united-coders.com/christian-harms/basic-rules-for-code-readability-and-the-if-statement
- Linux 内核C编程规范:http://www.kernel.org/doc/Documentation/CodingStyle
- 最后,强烈推荐你读一下Nokia的Qt的《API Design Principles》,其中的一条规则写成了本站的《千万不要用bool做函数参数》
其它
- 在OS X上使用gcc而不是xcode编译C++程序 https://github.com/kennethreitz/osx-gcc-installer
- 声讨PHP的一个slids http://zakx.de/phprant-en.pdf, 前面说到的两个网站都是使用PHP做到,不过,你可以通过这个PDF了解一下PHP有哪些地方不好。
- Infinite超级玛丽:(你可以比较一下,哪个版本不错)
—— 更新 2011.9.20 21:00 ——
@xzhaoyang 在留言中问我有没有C写CGI的文章,我看过最好的一篇是下面这篇:
http://www.tutorialspoint.com/cplusplus/cpp_web_programming.htm (注意fanqiang)
相关文章
- 2011年06月08日 -- 开源中最好的Web开发的资源
- 2011年02月16日 -- Web开发人员速查卡
- 2010年09月28日 -- 一些非常有意思的杂项资源
- 2011年03月04日 -- 一些有意思的贴子和工具
- 2010年11月22日 -- Jeff Dean的Stanford演讲
- 2010年09月09日 -- 你准备使用 HTML 5 吗?
- 2010年08月23日 -- 两个教程:Socket和HTML5
前几天酷壳发布过“vim简明攻略”,不知道大家练得怎么样了。如果你练了一下,那么这里这个速查卡就会对你有帮助了。以前本站也有过一个(vim速查卡),不过其太简单了。我觉得这个很不错,很全,很直观。这个速查卡来自这里。其用颜色标注了级别:
- Green = 存活级
- Yellow = 感觉良好
- Orange / Blue = 高级
- Red = 专家级
下面的图片点击可以看大图:
你还可以下载PDF版的和Excel版的,如果你是色盲的话,还有蓝色版PDF的。如果你不是很喜欢的话,这里还有几个:
- http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html
- http://tnerual.eriogerg.free.fr/vim.html
- http://www.lagmonster.org/docs/vi.html
- http://jrmiii.com/2009/03/06/learning-vim-the-pragmatic-way.html
相关文章
- 2011年09月20日 -- 一些文章和各种资源
- 2011年09月07日 -- 简明 Vim 练级攻略
- 2011年02月16日 -- Web开发人员速查卡
- 2011年01月18日 -- 一些有意思的网站和贴子
- 2010年10月18日 -- Eclipse和Vim快捷键桌面
- 2010年10月12日 -- 主流文本编辑器学习曲线
- 2010年10月09日 -- 三个教程
我们有很多Coding Style 或 代码规范。但这一条可能会经常被我们所遗忘,就是我们经常会在函数的参数里使用bool参数,这会大大地降低代码的可读性。不信?我们先来看看下面的代码。
当你读到下面的代码,你会觉得这个代码是什么意思?
widget->repaint(false);
是不要repaint吗?还是别的什么意思?看了文档后,我们才知道这个参数是immediate, 也就是说,false代表不立即重画,true代码立即重画。
Windows API中也有这样一个函数:InvalidateRect,当你看到下面的代码,你会觉得是什么意思?
InvalidateRect(hwnd, lpRect, false);
我们先不说InvalidateRect这个函数名取得有多糟糕,我们先说一下那个false参数?invalidate意为“让XXX无效”,false是什么意思?双重否定?是肯定的意思?如果你看到这样的代码,你会相当的费解的。于是,你要去看一下文档,或是InvalidateRect的函数定义,你会看到那个参数是 BOOL bErase,意思是,是否要重画背景。
这样的事情有很多,再看下面的代码,想把str中的”%USER%”替换成真实的用户名:
str.replace("%USER%", user, false); // Qt 3
TNND,那个false是什么意思?不替换吗?还是别的什么意思,看了文档才知道,false代码大小写不敏感的替换。
其实,如果你使用枚举变量/常量,而不是bool变量,你会让你的代码更易读,如:
widget->repaint(PAINT::immediate); widget->repaint(PAINT::deffer); InvalidateRect(hwnd, lpRect, !RepantBackground); str.replace("%USER%", user, Qt::CaseInsensitive); // Qt 4
如果对这个事不以为然的话,我们再来看一些别的示例,你不妨猜猜看看下面的代码:
component.setCentered(true, false);
这什么玩意儿啊?看了文档你才知道,这原来是 setCentered(centered, autoUpdate);
new Textbox(300, 100, false, true);
这又是什么啊?看了文档才知道,这是创建一个文本框,第三个参数是是否要滚动条,第四个是是否要自动换行。TNND。
上面的情况还不算最差,看看下面的双重否定。
component.setDisabled(false); filter.setCaseInsensitive(false)
再来一个,如果你读到下面的代码,相信你会和我一样,要么石化了,要么凌乱了。
event.initKeyEvent("keypress", true, true, null, null, false, false, false, false, 9, 0);
看完这篇文章,我希望你再也不要把bool为作为函数参数了。除非两个原因:
- 你100%确认不会带来阅读上的问题,比如Java的 setVisible (bool).
- 你100%确认你想去写出无法维护很难阅读的代码。
【更新2011/9/8】当然,别的参数也会有一样的问题,比如:new Textbox(300, 100, false, true);
中的300 和 100,不知道是坐标还是长宽,只不过,一般长度或坐标这样的参数都不会被hard code,都会有变量名,而bool这种参数经常性地被传成true 和 false。 bool参数表现得更为明显一些罢了。
所以,程序中不要出现magic number,true/false 也是一种 magic number。但是,我想告诉大家,从API设计的角度来说,你无法强制调用者用常量来取代true/false,定义成枚举类型是最好的选择。
最后,如果你想设计一个好的API,强烈推荐你读一下Nokia的Qt的《API Design Principles》,本文就是其中的“Boolean Trap”。
(全文完)
相关文章
vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的。下面的文章翻译自《Learn Vim Progressively》,我觉得这是给新手最好的VIM的升级教程了,没有列举所有的命令,只是列举了那些最有用的命令。非常不错。
——————————正文开始——————————
你想以最快的速度学习人类史上最好的文本编辑器VIM吗?你先得懂得如何在VIM幸存下来,然后一点一点地学习各种戏法。
Vim the Six Billion Dollar editor
Better, Stronger, Faster.
学习 vim 并且其会成为你最后一个使用的文本编辑器。没有比这个更好的文本编辑器了,非常地难学,但是却不可思议地好用。
我建议下面这四个步骤:
- 存活
- 感觉良好
- 觉得更好,更强,更快
- 使用VIM的超能力
当你走完这篇文章,你会成为一个vim的 superstar。
在开始学习以前,我需要给你一些警告:
- 学习vim在开始时是痛苦的。
- 需要时间
- 需要不断地练习,就像你学习一个乐器一样。
- 不要期望你能在3天内把vim练得比别的编辑器更有效率。
- 事实上,你需要2周时间的苦练,而不是3天。
第一级 – 存活
- 安装 vim
- 启动 vim
- 什么也别干!请先阅读
当你安装好一个编辑器后,你一定会想在其中输入点什么东西,然后看看这个编辑器是什么样子。但vim不是这样的,请按照下面的命令操作:
- 启 动Vim后,vim在 Normal 模式下。
- 让我们进入 Insert 模式,请按下键 i 。(陈皓注:你会看到vim左下角有一个–insert–字样,表示,你可以以插入的方式输入了)
- 此时,你可以输入文本了,就像你用“记事本”一样。
- 如果你想返回 Normal 模式,请按
ESC
键。
现在,你知道如何在 Insert 和 Normal 模式下切换了。下面是一些命令,可以让你在 Normal 模式下幸存下来:
i
→ Insert 模式,按ESC
回到 Normal 模式.x
→ 删当前光标所在的一个字符。:wq
→ 存盘 + 退出 (:w
存盘,:q
退出) (陈皓注::w 后可以跟文件名)dd
→ 删除当前行,并把删除的行存到剪贴板里p
→ 粘贴剪贴板推荐:
hjkl
(强例推荐使用其移动光标,但不必需) →你也可以使用光标键 (←↓↑→). 注:j
就像下箭头。:help <command>
→ 显示相关命令的帮助。你也可以就输入:help
而不跟命令。(陈皓注:退出帮助需要输入:q)
你能在vim幸存下来只需要上述的那5个命令,你就可以编辑文本了,你一定要把这些命令练成一种下意识的状态。于是你就可以开始进阶到第二级了。
当是,在你进入第二级时,需要再说一下 Normal 模式。在一般的编辑器下,当你需要copy一段文字的时候,你需要使用 Ctrl
键,比如:Ctrl-C
。也就是说,Ctrl键就好像功能键一样,当你按下了功能键Ctrl后,C就不在是C了,而且就是一个命令或是一个快键键了,在VIM的Normal模式下,所有的键就是功能键了。这个你需要知道。
标记:
- 下面的文字中,如果是
Ctrl-λ
我会写成<C-λ>
. - 以
:
开始的命令你需要输入<enter>
回车,例如 — 如果我写成:q
也就是说你要输入:q<enter>
.
第二级 – 感觉良好
上面的那些命令只能让你存活下来,现在是时候学习一些更多的命令了,下面是我的建议:(陈皓注:所有的命令都需要在Normal模式下使用,如果你不知道现在在什么样的模式,你就狂按几次ESC键)
-
各种插入模式
-
a
→ 在光标后插入 -
o
→ 在当前行后插入一个新行 -
O
→ 在当前行前插入一个新行 -
cw
→ 替换光标所在位置的一个单词
-
-
简单的移动光标
-
0
→ 数字零,到行头 -
^
→ 到本行第一个不是blank字符的位置(所谓blank字符就是空格,tab,换行,回车等) -
$
→ 到本行行尾 -
g_
→ 到本行最后一个不是blank字符的位置。 -
/pattern
→ 搜索pattern
的字符串(陈皓注:如果搜索出多个匹配,可按n键到下一个)
-
-
拷贝/粘贴 (陈皓注:p/P都可以,p是表示在当前位置之后,P表示在当前位置之前)
-
P
→ 粘贴 -
yy
→ 拷贝当前行当行于ddP
-
-
Undo/Redo
-
u
→ undo -
<C-r>
→ redo
-
-
打开/保存/退出/改变文件(Buffer)
-
:e <path/to/file>
→ 打开一个文件 -
:w
→ 存盘 -
:saveas <path/to/file>
→ 另存为<path/to/file>
-
:x
,ZZ
或:wq
→ 保存并退出 (:x
表示仅在需要时保存,ZZ不需要输入冒号并回车) -
:q!
→ 退出不保存:qa!
强行退出所有的正在编辑的文件,就算别的文件有更改。 -
:bn
和:bp
→ 你可以同时打开很多文件,使用这两个命令来切换下一个或上一个文件。(陈皓注:我喜欢使用:n到下一个文件)
-
花点时间熟悉一下上面的命令,一旦你掌握他们了,你就几乎可以干其它编辑器都能干的事了。但是到现在为止,你还是觉得使用vim还是有点笨拙,不过没关系,你可以进阶到第三级了。
第三级 – 更好,更强,更快
先恭喜你!你干的很不错。我们可以开始一些更为有趣的事了。在第三级,我们只谈那些和vi可以兼容的命令。
更好
下面,让我们看一下vim是怎么重复自己的:
-
.
→ (小数点) 可以重复上一次的命令 - N<command> → 重复某个命令N次
下面是一个示例,找开一个文件你可以试试下面的命令:
2dd
→ 删除2行3p
→ 粘贴文本3次100idesu [ESC]
→ 会写下 “desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu desu “.
→ 重复上一个命令—— 100 “desu “.3.
→ 重复 3 次 “desu” (注意:不是 300,你看,VIM多聪明啊).
更强
你要让你的光标移动更有效率,你一定要了解下面的这些命令,千万别跳过。
- N
G
→ 到第 N 行 (陈皓注:注意命令中的G是大写的,另我一般使用 : N 到第N行,如 :137 到第137行) -
gg
→ 到第一行。(陈皓注:相当于1G,或 :1) -
G
→ 到最后一行。 - 按单词移动:
-
w
→ 到下一个单词的开头。 -
e
→ 到下一个单词的结尾。
> 如果你认为单词是由默认方式,那么就用小写的e和w。默认上来说,一个单词由字母,数字和下划线组成(陈皓注:程序变量)
> 如果你认为单词是由blank字符分隔符,那么你需要使用大写的E和W。(陈皓注:程序语句)
-
下面,让我来说说最强的光标移动:
%
: 匹配括号移动,包括(
,{
,[
. (陈皓注:你需要把光标先移到括号上)*
和#
: 匹配光标当前所在的单词,移动光标到下一个(或上一个)匹配单词(*是下一个,#是上一个)
相信我,上面这三个命令对程序员来说是相当强大的。
更快
你一定要记住光标的移动,因为很多命令都可以和这些移动光标的命令连动。很多命令都可以如下来干:
<start position><command><end position>
例如 0y$
命令意味着:
-
0
→ 先到行头 -
y
→ 从这里开始拷贝 -
$
→ 拷贝到本行最后一个字符
你可可以输入 ye
,从当前位置拷贝到本单词的最后一个字符。
你也可以输入 y2/foo
来拷贝2个 “foo” 之间的字符串。
还有很多时间并不一定你就一定要按y才会拷贝,下面的命令也会被拷贝:
-
d
(删除 ) -
v
(可视化的选择) -
gU
(变大写) -
gu
(变小写) - 等等
第四级 – Vim 超能力
你只需要掌握前面的命令,你就可以很舒服的使用VIM了。但是,现在,我们向你介绍的是VIM杀手级的功能。下面这些功能是我只用vim的原因。
在当前行上移动光标: 0
^
$
f
F
t
T
,
;
0
→ 到行头^
→ 到本行的第一个非blank字符$
→ 到行尾g_
→ 到本行最后一个不是blank字符的位置。fa
→ 到下一个为a的字符处,你也可以fs到下一个为s的字符。t,
→ 到逗号前的第一个字符。逗号可以变成其它字符。3fa
→ 在当前行查找第三个出现的a。F
和T
→ 和f
和t
一样,只不过是相反方向。
还有一个很有用的命令是 dt"
→ 删除所有的内容,直到遇到双引号—— "。
区域选择 <action>a<object>
或 <action>i<object>
在visual 模式下,这些命令很强大,其命令格式为
<action>a<object>
和 <action>i<object>
- action可以是任何的命令,如
d
(删除),y
(拷贝),v
(可以视模式选择)。 - object 可能是:
w
一个单词,W
一个以空格为分隔的单词,s
一个句字,p
一个段落。也可以是一个特别的字符:"、
'、
)、
}、
]。
假设你有一个字符串 (map (+) ("foo"))
.而光标键在第一个 o
的位置。
vi"
→ 会选择foo
.va"
→ 会选择"foo"
.vi)
→ 会选择"foo"
.va)
→ 会选择("foo")
.v2i)
→ 会选择map (+) ("foo")
v2a)
→ 会选择(map (+) ("foo"))
块操作: <C-v>
块操作,典型的操作: 0 <C-v> <C-d> I-- [ESC]
-
^
→ 到行头 -
<C-v>
→ 开始块操作 -
<C-d>
→ 向下移动 (你也可以使用hjkl来移动光标,或是使用%,或是别的) -
I-- [ESC]
→ I是插入,插入“--
”,按ESC键来为每一行生效。
在Windows下的vim,你需要使用 <C-q>
而不是 <C-v>
,<C-v>
是拷贝剪贴板。
自动提示: <C-n>
和 <C-p>
在 Insert 模式下,你可以输入一个词的开头,然后按 <C-p>或是<C-n>,自动补齐功能就出现了……
宏录制: qa
操作序列 q
, @a
, @@
-
qa
把你的操作记录在寄存器a。
- 于是
@a
会replay被录制的宏。 -
@@
是一个快捷键用来replay最新录制的宏。
示例
在一个只有一行且这一行只有“1”的文本中,键入如下命令:
qaYp<C-a>q
→
qa
开始录制Yp
复制行.<C-a>
增加1.q
停止录制.@a
→ 在1下面写下 2@@
→ 在2 正面写下3- 现在做
100@@
会创建新的100行,并把数据增加到 103.
可视化选择: v
,V
,<C-v>
前面,我们看到了 <C-v>
的示例 (在Windows下应该是<C-q>),我们可以使用 v
和 V
。一但被选好了,你可以做下面的事:
-
J
→ 把所有的行连接起来(变成一行) -
<
或>
→ 左右缩进 -
=
→ 自动给缩进 (陈皓注:这个功能相当强大,我太喜欢了)
在所有被选择的行后加上点东西:
<C-v>
- 选中相关的行 (可使用
j
或<C-d>
或是/pattern
或是%
等……) -
$
到行最后 -
A
, 输入字符串,按ESC。
分屏: :split
和 vsplit
.
下面是主要的命令,你可以使用VIM的帮助 :help split
. 你可以参考本站以前的一篇文章VIM分屏。
:split
→ 创建分屏 (:vsplit
创建垂直分屏)<C-w><dir>
: dir就是方向,可以是hjkl
或是 ←↓↑→ 中的一个,其用来切换分屏。<C-w>_
(或<C-w>|
) : 最大化尺寸 (<C-w>| 垂直分屏)<C-w>+
(或<C-w>-
) : 增加尺寸
结束语
- 上面是作者最常用的90%的命令。
- 我建议你每天都学1到2个新的命令。
- 在两到三周后,你会感到vim的强大的。
- 有时候,学习VIM就像是在死背一些东西。
- 幸运的是,vim有很多很不错的工具和优秀的文档。
- 运行vimtutor直到你熟悉了那些基本命令。
- 其在线帮助文档中你应该要仔细阅读的是
:help usr_02.txt
. - 你会学习到诸如
!,
目录,寄存器,插件等很多其它的功能。
学习vim就像学弹钢琴一样,一旦学会,受益无穷。
——————————正文结束——————————
对于vi/vim只是点评一点:这是一个你不需要使用鼠标,不需使用小键盘,只需要使用大键盘就可以完成很多复杂功能文本编辑的编辑器。不然,Visual Studio也不就会有vim的插件了。
(全文完)
相关文章
- 2011年09月20日 -- 一些文章和各种资源
- 2011年09月16日 -- 给程序员的VIM速查卡
- 2010年10月18日 -- Eclipse和Vim快捷键桌面
- 2010年10月12日 -- 主流文本编辑器学习曲线
- 2010年10月09日 -- 三个教程
- 2010年09月28日 -- 一些非常有意思的杂项资源
- 2009年12月04日 -- Visual Studio的Vim插件
本文来自“The most stupid C bug ever”,很有意思,分享给大家。我相信这样的bug,就算你是高手你也会犯的。你来看看作者犯的这个Bug吧。。
首先,作者想用一段程序来创建一个文件,如果有文件名的话,就创建真正的文件,如果没有的话,就调用?tmpfile()?创建临时文件。他这段程序就是HTTP下载的C程序。code==200就是HTTP的返回码。
else if (code == 200) { // Downloading whole file /* Write new file (plus allow reading once we finish) */ g = fname ? fopen(fname, "w+") : tmpfile(); }
但是这个程序,只能在Unix/Linux下工作,因为 Microsoft 的?tmpfile()的实现?居然选择了 C:\ 作为临时文件的存放目录,这对于那些没有管理员权限的人来说就出大问题了,在Windows 7下,就算你有管理员权限也会有问题。所以,上面的程序在Windows平台下需要用不同的方式来处理,不能直接使用Windows的tmpfile()函数。
于是作者就先把这个问题记下来,在注释中写下了FIXME:
else if (code == 200) { // Downloading whole file /* Write new file (plus allow reading once we finish) */ // FIXME Win32 native version fails here because // Microsoft's version of tmpfile() creates the file in C:\ g = fname ? fopen(fname, "w+") : tmpfile(); }
然后,作者觉得需要写一个跨平台的编译:
FILE * tmpfile ( void ) { #ifndef _WIN32 return tmpfile(); #else //code for Windows; #endif }
然后,作者觉得这样实现很不好,会发现名字冲突,因为这样一来这个函数太难看了。于是他重构了一下他的代码——写一个自己实现的tmpfile() – w32_tmpfile,然后,在Windows 下用宏定义来重命名这个函数为tmpfile()。(陈皓注:这种用法是比较标准的跨平台代码的写法)
#ifdef _WIN32 #define tmpfile w32_tmpfile #endif FILE * w32_tmpfile ( void ) { //code for Windows; }
搞定!编译程序,运行。靠!居然没有调用到我的w32_tmpfile(),什么问题?调试,单步跟踪,果然没有调用到!难道是问号表达式有问题?改成if – else 语句,好了!
if(NULL != fname) { g = fopen(fname, "w+"); } else { g = tmpfile(); }
问号表达式不应该有问题吧,难道我们的宏对问号表达式不起作用,这难道是编译器的预编译的一个bug?作者怀疑到。
现在我们把所有的代码连在一起看,并比较一下:
能正常工作的代码
#ifdef _WIN32 # define tmpfile w32_tmpfile #endif FILE * w32_tmpfile ( void ) { code for Windows; } else if (code == 200) { // Downloading whole file /* Write new file (plus allow reading once we finish) */ // FIXME Win32 native version fails here because // Microsoft's version of tmpfile() creates the file in C:\ //g = fname ? fopen(fname, "w+") : tmpfile(); if(NULL != fname) { g = fopen(fname, "w+"); } else { g = tmpfile(); } }
不能正常工作的代码
#ifdef _WIN32 # define tmpfile w32_tmpfile #endif FILE * w32_tmpfile ( void ) { code for Windows; } else if (code == 200) { // Downloading whole file /* Write new file (plus allow reading once we finish) */ // FIXME Win32 native version fails here because // Microsoft's version of tmpfile() creates the file in C:\ g = fname ? fopen(fname, "w+") : tmpfile(); }
也许你在一开始就看到了这个bug,但是作者没有。所有的问题都出在注释上:
/* Write new file (plus allow reading once we finish) */ // FIXME Win32 native version fails here because // Microsoft's version of tmpfile() creates the file in C:\
你看到了最后那个C:\吗?在C中,“\” 代表此行没有结束,于是,后面的代码也成了注释。这就是这个bug的真正原因!
而之所以改成if-else能工作的原因是因为作者注释了老的问号表达式的代码,所以,那段能工作的代码成了:
/* Write new file (plus allow reading once we finish) */ // FIXME Win32 native version fails here because Microsoft's version of tmpfile() creates the file in C: //g = fname ? fopen(fname, "w+") : tmpfile(); if(NULL != fname) { g = fopen(fname, "w+"); } else { g = tmpfile(); }
我相信,当作者找到这个问题的原因后,一定会骂一句“妈的”!我也相信,这个bug花费了作者很多时间!
最后,我也share一个我以前犯的一个错。
我有一个小函数,需要传入一个int* pInt的类型,然后我需要在我的代码里 把这个int* pInt作除数。于是我的代码成了下面的这个样子:
float result = num/*pInt;
…./* some comments */
-x<10 ? f(result):f(-result);
因为我在我当时用vi编写代码,所以没有语法高亮,而我的程序都编译通过了,但是却出现了很奇怪的事。我也不知道,用gdb调式的时候,发现有些语句直接就过了。这个问题让我花了很多时间,最后发现问题原来是没有空格导致的,TNND,下面我用代码高亮的插件来显示上面的代码,
float result = num/*pInt; .... /* some comments */ -x<10 ? f(result):f(-result);
Holly Shit! 我的代码成了:
float result = num-x<10 ? f(result):f(-result);
妈的!我的这个错误在愚蠢程度上和上面那个作者出的错误有一拼。
(全文完)
相关文章
- 2011年07月18日 -- 程序员技术练级攻略
- 2011年06月03日 -- 如何写出无法维护的代码
- 2011年03月29日 -- 如何学好C语言
- 2010年04月01日 -- C++ 程序员自信心曲线图
- 2010年03月30日 -- “21天教你学会C++”
- 2009年12月24日 -- 程序员眼中的编程语言
- 2011年09月21日 -- 如果你看不见你还能编程吗?
Web上的用户登录功能应该是最基本的功能了,可是在我看过一些站点的用户登录功能后,我觉得很有必要写一篇文章教大家怎么来做用户登录功能。下面的文章告诉大家这个功能可能并没有你所想像的那么简单,这是一个关系到用户安全的功能,希望大家能从下面的文章中能知道什么样的方法才是一个好的用户登录功能。以下内容,转载时请保持原文一致,并请注明作者和出处。
用户名和口令
首先,我们先来说说用户名和口令的事。这并不是本站第一次谈论这个事了。如何管理自己的口令让你知道怎么管理自己的口令,破解你的口令让你知道在现代这样速度的计算速度下,用穷举法破解你的口令可能会是一件很轻松的事。在这里我想告诉从开发者的角度上来做设计这个用户名和口令的事。下面一几件规则:
- 限制用户输入一些非常容易被破解的口令。如什么qwert,123456, password之类,就像twitter限制用户的口令一样做一个口令的黑名单。另外,你可以限制用户口令的长度,是否有大小写,是否有数字,你可以用你的程序做一下校验。当然,这可能会让用户感到很不爽,所以,现在很多网站都提供了UX让用户知道他的口令强度是什么样的(比如这个有趣的UX),这样可以让用户有一个选择,目的就是告诉用户——要想安全,先把口令设得好一点。
- 千万不要明文保存用户的口令。正如如何管理自己的口令所说的一样,很多时候,用户都会用相同的ID相同的口令来登录很多网站。所以,如果你的网站明文保存的话,那么,如果你的数据被你的不良员工流传出去那对用户是灾难性的。所以,用户的口令一定要加密保存,最好是用不可逆的加密,如MD5或是SHA1之类的有hash算法的不可逆的加密算法。CSDN曾明文保存过用户的口令。(另,对于国内公司的品行以及有关部门的管理方式,我不敢保证国内网站以加密的方式保存你的口令。我觉得,做为一个有良知的人,我们应该加密保存用户的口令)
- 是否让浏览器保存口令。我们有N多的方法可以不让浏览器保存用户名和口令。但是这可能对用户来说很不爽。因为在真实世界里谁也记得不住那么多的口令。很多用户可能会使用一些密码管理工具来保存密码,浏览器只是其中一种。是否让浏览器保存这个需要你做决定,重点是看一下你的系统的安全级别是否要求比较高,如果是的话,则不要让浏览器保存密码,并在网站明显的位置告诉用户——保存口令最安全的地方只有你的大脑。
- 口令在网上的传输。因为HTTP是明文协议,所以,用户名和口令在网上也是明文发送的,这个很不安全。你可以看看这篇文章你就明白了。要做到加密传输就必需使用HTTPS协议。但是,在中国还是有很多网站的Web登录方式还在使用ActiveX控件,这可能成为IE6还大量存在的原因。我通常理解为这些ActiveX控件是为了反键盘记录程序的。 不过,我依然觉ActiveX控件不应该存在,因为在国外的众多安全很重要的站点上都看不到ActiveX的控件的身影。
用户登录状态
首先,我想告诉大家的是,因为HTTP是无状态的协议,也就是说,这个协议是无法记录用户访问状态的,其每次请求都是独立的无关联的,一笔是一笔。而我们的网站都是设计成多个页面的,所在页面跳转过程中我们需要知道用户的状态,尤其是用户登录的状态,这样我们在页面跳转后我们才知道是否可以让用户有权限来操作一些功能或是查看一些数据。
所以,我们每个页面都需要对用户的身份进行认证。当然,我们不可能让用户在每个页面上输入用户名和口令,这会让用户觉得我们的网站相当的SB。为了实现这一功能,用得最多的技术就是浏览器的cookie,我们会把用户登录的信息存放在客户端的cookie里,这样,我们每个页面都从这个cookie里获得用户是否登录的信息,从而达到记录状态,验证用户的目的。但是,你真的会用cookie吗?下面是使用cookie的一些原则。
- 千万不要在cookie中存放用户的密码。加密的密码都不行。因为这个密码可以被人获取并尝试离线穷举。所以,你一定不能把用户的密码保存在cookie中。我看到太多的站点这么干了。
-
正确设计“记住密码”。这个功能简直就是一个安全隐患,我觉得并不是所有的程序员都知道怎么设计这个事。一般的设计 是——一时用户勾选了这个功能,系统会生成一个cookie,cookie包括用户名和一个固定的散列值,这个固定的散列值一直使用。这样,你就可以在所有的设备和客户上都可以登录,而且可以有多个用户同时登录。这个并不是很安全。下面是一些更为安全的方法供你参考:
(——更新 2011/08/26,原文中有些小错误,并且说的不清楚,重新调整了一下——)
1)在cookie中,保存三个东西——用户名,登录序列,登录token。
用户名:明文存放。
登录序列:一个被MD5散列过的随机数,仅当强制用户输入口令时更新(如:用户修改了口令)。
登录token:一个被MD5散列过的随机数,仅一个登录session内有效,新的登录session会更新它。
2)上述三个东西会存在服务器上,服务器的验证用户需要验证客户端cookie里的这三个事。
3)这样的设计会有什么样的效果,会有下面的效果,
a)登录token是单实例登录。意思就是一个用户只能有一个登录实例。
b)登录序列是用来做盗用行为检测的。如果用户的cookie被盗后,盗用者使用这个cookie访问网站时,我们的系统是以为是合法用户,然后更新“登录token”,而真正的用户回来访问时,系统发现只有“用户名”和“登录序列”相同,但是“登录token” 不对,这样的话,系统就知道,这个用户可能出现了被盗用的情况,于是,系统可以清除并更改登录序列 和 登录token,这样就可以令所有的cookie失效,并要求用户输入口令。并给警告用户系统安全。
4)当然,上述这样的设计还是会有一些问题,比如:同一用户的不同设备登录,甚至在同一个设备上使用不同的浏览器保登录。一个设备会让另一个设备的登录token和登录序列失效,从而让其它设备和浏览器需要重新登录,并会造成cookie被盗用的假象。所以,你在服务器服还需要考虑- IP 地址,
a) 如果以口令方式登录,我们无需更新服务器的“登录序列”和 “登录token”(但需要更新cookie)。因为我们认为口令只有真正的用户知道。
b) 如果 IP相同 ,那么,我们无需更新服务器的“登录序列”和 “登录token”(但需要更新cookie)。因为我们认为是同一用户有同一IP(当然,同一个局域网里也有同一IP,但我们认为这个局域网是用户可以控制的。网吧内并不推荐使用这一功能)。
c) 如果 (IP不同 && 没有用口令登录),那么,“登录token” 就会在多个IP间发生变化(登录token在两个或多个ip间被来来回回的变换),当在一定时间内达到一定次数后,系统才会真正觉得被盗用的可能性很高,此时系统在后台清除“登录序列”和“登录token“,让Cookie失效,强制用户输入口令(或是要求用户更改口令),以保证多台设备上的cookie一致。
- 不要让cookie有权限访问所有的操作。否则就是XSS攻击,这个功能请参看新浪微博的XSS攻击。下面的这些功能一定要用户输入口令:
- 权衡Cookie的过期时间。如果是永不过期,会有很不错的用户体验,但是这也会让用户很快就忘了登录密码。如果设置上过期期限,比如2周,一个月,那么可能会好一点,但是2周和一个月后,用户依然会忘了密码。尤其是用户在一些公共电脑上,如果保存了永久cookie的话,等于泄露了帐号。所以,对于cookie的过期时间我们还需要权衡。
找回口令的功能
找回口令的功能一定要提供。但是很多朋友并不知道怎么来设计这个功能。我们有很多找回口令的设计,下面我逐个点评一下。
- 千万不要使用安全问答。事实证明,这个环节很烦人,而且用户并不能很好的设置安全问答。什么,我的生日啊,我母亲的生日,等等。因为今天的互联网和以前不一样了,因为SNS,今天的互联比以前更真实了,我可以上facebook,开心,人人网,LinkedIn查到你的很多的真实的信息。通过这些信息我可以使用安全问答来重设你的口令。 这里需要说一下 Facebook,Facebook的安全问答很强大,还要你通过照片认人,呵呵。
- 不要重置用户的密码。因为这有可能让用户的密码遭到恶意攻击。当然,你要发个邮件给用户让其确认,用户点击邮件中的一个链接,你再重置。我并不推荐这样的方法,因为用户一般都会用笔记下来这个很难记的口令,然后登录系统,因为登录系统时使用了“记住密码”的功能,所以导致用户不会去修改密码,从而要么导到被写下来的密码被人盗取,要么又忘记了密码。
- 好一点的做法——通过邮件自行重置。当用户申请找回口令功能的时候,系统生成一个MD5唯一的随机字串(可通过UID+IP+timestamp+随机数),放在数据库中,然后设置上时限(比如1小时内),给用户发一个邮件,这个连接中包含那个MD5的字串的链接,用户通过点击那个链接来自己重新设置新的口令。
- 更好一点的做法——多重认证。比如:通过手机+邮件的方式让用户输入验证码。手机+邮件可能还不把握,因为手机要能会丢了,而我的手机可以访问我的邮箱。所以,使用U盾,SecureID(一个会变化的6位数token),或是通过人工的方式核实用户身份。当然,这主要看你的系统的安全级别了。
口令探测防守
- 使用验证码。验证码是后台随机产生的一个短暂的验证码,这个验证码一般是一个计算机很难识别的图片。这样就可以防止以程序的方式来尝试用户的口令。事实证明,这是最简单也最有效的方式。当然,总是让用户输入那些肉眼都看不清的验证码的用户体验不好,所以,可以折中一下。比如Google,当他发现一个IP地址发出大量的搜索后,其会要求你输入验证码。当他发现同一个IP注册了3个以上的gmail邮箱后,他需要给你发短信方式或是电话方式的验证码。
- 用户口令失败次数。调置口令失败的上限,如果失败过多,则把帐号锁了,需要用户以找回口令的方式来重新激活帐号。但是,这个功能可能会被恶意人使用。最好的方法是,增加其尝试的时间成本(以前的这篇文章说过一个增加时间成本的解密算法)。如,两次口令尝试的间隔是5秒钟。三次以上错误,帐号被临时锁上30秒,5次以上帐号被锁1分钟,10次以上错误帐号被锁4小时……
- 系统全局防守。上述的防守只针对某一个别用户。恶意者们深知这一点,所以,他们一般会动用“僵尸网络”轮着尝试一堆用户的口令,所以上述的那种方法可能还不够好。我们需要在系统全局域上监控所有的口令失败的次数。当然,这个需要我们平时没有受到攻击时的数据做为支持。比如你的系统,平均每天有5000次的口令错误的事件,那么你可以认为,当口令错误大幅超过这个数后,而且时间相对集中,就说明有黑客攻击。这个时候你怎么办?一般最常见使用的方法是让所有的用户输错口令后再次尝试的时间成本增加。
参考文章
- OWASP Guide To Authentication
- Dos and Don’ts of Client Authentication on the Web (PDF)
- Charles Miller’s Persistent Login Cookie Best Practice
- Wikipedia: HTTP cookie
- Personal knowledge questions for fallback authentication: Security questions in the era of Facebook
相关文章
- 2011年03月03日 -- 另类UX让你输入强口令
- 2011年03月02日 -- 破解你的口令
- 2010年05月20日 -- Twitter的禁用口令
- 2010年05月18日 -- 如何管理并设计你的口令
- 2010年02月01日 -- 如何防范密码被破解
- 2011年09月20日 -- 一些文章和各种资源
- 2011年08月17日 -- 国内微博和Twitter的最大不同
【感谢网友sumtec投递此文,很欢乐也有意思,与大家共勉】
首先说明:
1、以下特征是真实遇到过的,同事犯过的,乃至我自己也犯过的;
2、为了剧情需要,某些例子进行了一些夸张修饰等演绎创作,如无雷同,请勿生气;
3、如果你出现过以下症状之一,并不代表你就是弱爆了,但是如果你一直出现,乃至一说到这个大家就能联想到你,那么你就得小心了;
4、如果你是集这几个的大乘者,恭喜你,你已经找到了离开这个行业的充足理由了。
好了,搞定!
“那个Bug解决了吗?”
“好了,搞定!”
“这么快?”
正当你非常欣喜的时候,就传来了噩耗:刚才还能编译成功的,就失败了。(好吧,我们的集成编译尚未成功配置上,理论上这种事情应该会被退回。)又或者能编译成功,但是呢,原来明明能起作用的一个下拉框,突然发神经的不起作用了。最隐蔽的莫过于,一切正常,但是当你看到代码的时候,你就晕厥过去了。比如我们曾经发现了一个Bug,简单说就是每次用户点击某个东西,就会执行下面的这段C#代码:
controlPropertyPanel.PropertyChanged += this.UpdatePropertyOnChanged;
这个Bug很明显会导致速度越来越慢,因为同一个更新操作会被更新N次,并且这个N会越来越大。其实这个Bug已经够弱了,但是后来居然被修改为:
controlPropertyPanel.PropertyChanged -= this.UpdatePropertyOnChanged; controlPropertyPanel.PropertyChanged += this.UpdatePropertyOnChanged;
这段代码能编译,能执行,但是就是弱爆了。因为这不仅仅没有从根本上去掉造成问题的逻辑,还会带来更多的困惑:为什么要先减后加呢?
这类特征,请大家看看有趣的《各种流行的编程风格》,我这个例子算是一种撞大运。我觉这吧,这类问题都是因为只想解决一些表面的东西为目的,完全不管底下的其它任何问题而造成的。
那估计是他的Bug
“这个问题为啥还没解决呢?”
“我觉得应该是他那里边的Bug,我调不了。”
“哦……”
这个“他”可以是某一位同事,或者前同事,或者微软,或者别的什么公司,再或者某个开源代码的作者。这些个我都遇到过,比如说是另一位现在在职的同事吧。当你告诉这位同事这个Bug似乎在他那儿,并且问问什么时候解决,他也许会很愧疚的立刻调试,可最后结果却仍然是开头对话主人翁的所写代码的问题。
再比如说是微软吧,那么对话可能就会包括:“啊,SilverLight真是烂,老是内存泄漏、崩溃等……”“是啊是啊!烂死了!早知道用Flash了。”又或者会说:“微软就是烂,Java就是好。”其实,我不想比较什么SilverLight还是Flash,.NET还是Java。因为在讨论这些问题之前,先最好想想,这真的是别人的错么?相信是其他人的错是一件很简单的事情,因为这样推脱之后你就可以啥都不做了,反正不是我的错。
如果真的发现了这是别人的Bug并证明了,那倒好说。但这种特征是一种纯粹的怀疑,并没有丝毫的证明。在仔细找了自己所有可能犯的错之后,如果你怀疑是别人的问题,那请求证一下。
无图无真相!
“楼主,无图无真相啊!”
“楼主,无代码无真相啊!”
“楼主,给翻译一下啊!”
据说Linus在别人询问Linux内存管理的一个什么问题时,回答道“Read the fxxxing source code”,很多时候我也有类似的冲动。我发现在信息发达的时代,不少人的阅读能力、动手能力都严重退化了。这些人最好就是你亲自来帮他把问题解决了,他才不想了解里面到底 发生了什么。这种问题体现在博客里面,就是寄希望于你写得图文并茂,图嘛最好花里胡哨同时言简而意概,文字嘛最好大段大段的代码。其实图不是重要的,只是为了好看,重点是代码,这样他一Copy就可以直接解决他们的问题了。
比方说,Silverlight里面没有各种图像格式的编码器,于是当你希望保存Jpg的时候怎么办呢?Google一下,发现原来有人写过一个FluxJpeg的编码器。下载下来一跑,唉还真能用哎。之后就直接签入,也不捎带看一下有没有什么问题,或者设计不合理的地方。(其实真的有,会很慢,因为有大量毫无必要的数组拷贝。)
又或者说,遇到了某个Bug,搜索一下发现,哎,还真有人遇到过,而且还有代码哎!把代码扒下来一跑,发现好像解决了,至于为什么就不管了。甚至还遇到过根本就不管解决不解决问题,反正代码扒下来了就签入了的。
再比如,写一篇博客讲解如何缩减.NET编译出来的文体大小,其中提到许多概念需要先阅读微软官方的一个文档。结果,还是会有人回复说,你那个文章里面提到那么多的Blob,也不说说Blob里面都有什么,大概是很不满意吧。可是这个文档里面都有啊,难道就不能自己阅读一下?其实即便我连这个文档都没有给出,自己也应该有这个能力去进行思考,去动手寻找。
千万不要退化成一个啥都要别人给你嚼烂了才能够吞下去,吞下去也不会消化吸收的人。这样的人大概别人给的是大便,只要有代码无真相,也会照样吃下去的。若真如此,那你打算如何提高呢?
那是个对象!
“这个ExpressionVisitor,它是用来干什么的?”
“……”
“好吧,或者这么说,他是一个什么东西?”
“他是一个对象!”
“啊?”
“哦,是一个对象的实例。”
大概这样的回答,和那个微软工程师说“你在直升飞机上”差不多——反正你也不能说是错的,但是就是没什么意义。其实不知道没啥问题,人又不是神,怎么可能都知道呢?不去仔细了解和学习问题也不严重,因为你可以改。但是当你习惯性的随便找一个绝对没错但又不说明任何问题的答案,甚至似是而非的东西来对付的时候,你就离弱爆的边缘很近了。
当然,上面的对话也许是比较极端的。一个稍弱一点的对话版本是:
“这个内存泄漏是怎么造成的呢?”
“嗯,会不会是图片放的位置不对呢?”
哈,还是很夸张对吧?没办法,写博客有时候需要夸张的文字,否则你无法理解我的意思是:有时候,大家会倾向于从自己的记忆中寻找一些相似的物品,然后选择相似度自认为比较高的东西出来当作答案,而全然不管两者之间的逻辑是否有哪怕那么一丝的关联。也许很多时候,我们确实需要从相似的东西开始,但请别把他当作终点。程序是需要严谨的逻辑的,所以你也必须非常严谨的去推演。
关于这类的问题真的太多太多了,比如我指着下面这段代码当中的红字:
var dictionary = new Dictionary<string, string>();
dictionary["someKey"] = “someValue”;
“这句话说明了什么?”
“说明dictionary是一个数组。”
集大成者
最后我举一个集大成者的例子,说,有个任务是要在SilverLight应用上面添加一个“收藏本站点”。好,怎么解决呢?网上一搜,发现有很多这样的代码:
function AddBookmark(Url, LabeName) { if (document.all) { window.external.addFavorite(Url, LabeName); } else if (window.sidebar) { window.sidebar.addPanel(LabeName, Url, ''); } }
然后直接扒下来就放上去了,通过某种方式在SilverLight中调用这段JavaScript,签入,搞定了!结果到了测试那边发现完全不能用,无论在IE6/7/8/9/10,还是在FireFox/Safari/Chrome上面,都不能使用。我问:
“这是什么原因呢?”
“不知道,反正浏览器报告没有权限,可能是浏览器的安全设置原因吧,或者操作系统的Bug,也可能是浏览器的某种Bug?”
“不可能啊?这些代码存在很多年了,要有问题早就能在网上搜索到了。”
“那也许是SilverLight调用的时候有什么安全问题。哎!SilverLight好烦啊!”
“那怎么还没有解决呢?”
“好,我马上解决它!”
很快,那段Javascript就变成了:
function AddBookmark(Url, LabeName) { try { if (document.all) { window.external.addFavorite(Url, LabeName); } else if (window.sidebar) { window.sidebar.addPanel(LabeName, Url, ''); } } catch { alert("您的浏览器因为安全设置的问题无法收藏,请手动添加收藏!"); } }
看到这样的代码,我彻底震惊了。亲自调试了一下,发现确实报告了一个“没有权限”的异常。但是,我还发现,那个Url参数的值是“www.adomainname.com\test\page.html”。那这不废话么!浏览器认为你要收藏的是一个本地硬盘上的路径,怎么可能在一个Internet Zone上允许收藏这种路径呢?我于是指着代码问:
“这个Url是什么?”
“是一个变量”
“啊?”
“哦,不对,是一个参数。”
你是否也有类似的经历呢?
(全文完)
相关文章
- 2010年09月25日 -- 代码重构的一个示例
- 2010年01月22日 -- 各种流行的编程风格
- 2011年09月21日 -- 如果你看不见你还能编程吗?
- 2011年09月08日 -- 千万不要把 bool 设计成函数参数
- 2011年08月26日 -- C语言中史上最愚蠢的Bug
- 2011年08月16日 -- 重构代码的7个阶段
- 2011年08月01日 -- 你确信你了解时间吗?
发表评论
-
javaEE学习笔记
2012-05-14 22:00 9261.错误描述 增量部署 http://localhos ... -
二维码收集
2011-07-25 10:36 991二维码已经不是什么 ... -
电脑硬件故障维修教程
2011-07-13 22:26 1042硬件故障虽然多种多样,但其维修流程仍然遵循一定的原理,本节介 ... -
苹果冷落了 iAd
2011-06-08 09:07 927或许你还记得苹果的广告产品 i ... -
Groupon 创始人把目光转向「网络当铺]
2011-06-08 09:05 758Groupon 联合创始人 E ... -
如何升级到iOS 5(无需开发者帐号)
2011-06-08 09:02 1140看过昨天苹果在WWDC 上介绍过iOS ... -
微博型态
2011-06-07 23:37 707在一个快速发展的新兴市场 ... -
苹果2011年全球开发者大会图文实录
2011-06-07 13:47 1100新浪科技讯 北京时间6月7日凌晨消息,2011年 ... -
eBay收购Magento 以增强电子商务开发工具
2011-06-07 13:44 780网易科技讯 6月7日消息,据国外媒体报道,eBa ... -
一款全太阳能驱动笔记本
2011-06-07 13:22 736... -
微软演示Windows 8,全新的界面,全新的触摸体验
2011-06-07 13:07 757微软刚刚在D9大会上首次演示了Win ... -
新浪Q微博截图泄露:重大改头换面,盈利模式初现
2011-06-07 12:54 1141近日,新浪Q微博的一张截图 被用户@吾空孙 贴了 ... -
Adobe CEO 称和苹果的 Flash 之争已经结束
2011-06-07 09:44 936Flash 和 HTML5 之争 从未停 ... -
mac下如何编辑word文档
2011-06-05 00:58 6在mac上安装open office ,open office ... -
转载 2011 年 IT 行业十大热门技术领域 收藏
2011-05-06 15:40 816... -
Delicious被Yahoo卖了
2011-04-29 08:40 1014据Delicious官方博客报道 ,YouTub ... -
如何让自己的网站在google搜索引擎中排名靠前?
2011-04-21 16:10 1664第一:直接在google做关键字排名 第二:seo搜索引擎优 ... -
如何知道一个网站的流量
2011-04-19 11:18 12321、 外链:可以登录雅虎国外站yahoo.com ...
相关推荐
【标题】:“转载牛人文章学习” 这篇标题表明我们即将探讨的是某位业内专家或博主的文章,关于IT行业的某个主题,特别是与Android相关的技术。在IT领域,"牛人"通常指的是那些在某一技术领域有深厚造诣的人,他们...
转载的文章——oracle11g_RAC_启动和停止操作说明
本篇文章将深入探讨如何使用Axure这一原型设计工具,来创建出富有吸引力的手机壳产品设计原型。 Axure是一款广泛应用于产品经理、交互设计师和UI设计师手中的原型设计软件,以其强大的交互功能和快速原型制作能力受...
### 如何一键转载好文章到QQ空间 #### 一、引言 随着互联网技术的发展,人们在日常生活中越来越依赖网络获取信息。当我们遇到一篇有价值的文章时,常常希望能够将其分享到自己的社交平台上,以便让更多人受益。QQ...
在IT行业中,网络内容的分享和传播是常见现象,但如何正确、完整地转载他人的文章,特别是技术类文章,避免格式混乱,是一项需要注意的技巧。这篇教程将带你了解如何在CSDN(China Software Developer Network)这个...
【RiPro7+站壳4.0文章左上角标签美化版】jizhi-chlid极致主题4.0是一款专为WordPress设计的高级主题,它集成了RiPro7插件和站壳4.0的功能,旨在提供一个美观、功能丰富的文章展示平台。这个主题在文章左上角特别强调...
文章表则包括文章ID、作者ID(与用户表关联)、文章标题、内容、发布时间等字段。 2. **用户认证**: - 系统可能包含用户注册和登录功能。用户通过输入用户名和密码进行身份验证。PHP的`password_hash`和`password...
本文将详细解析标题“wordpress主题RiPro7.2+jizhi-chlid极致主题4.0+站壳4.0文章左上角标签美化”以及其描述所涵盖的知识点。 首先,我们要了解的是WordPress的主题。主题是WordPress的核心组成部分之一,它决定了...
新浪、百度、和讯、网易、搜狐、凤凰、39健康博客、天涯、摇篮网、CSDN、ChinaUnix、中国教育服务平台(成长博客)、博客园、51cto、歪酷博客、草根博客等等,如果还有较多用户需要增加支持某个博客,也会更新的。...
徐州天科机械制造有限公司的李志伟所撰写的文章中,提出了开发一种过渡胶带转载机的设计方案,用于解决上述问题。这种过渡胶带转载机由两个桥式单元组成,它们是可动的,可以相互伸缩和定量旋摆,并且各自由电动滚筒...
我个人自己钻研解决了thinkpad黑将s5深感摄像头不能使用的解决方法。之前,联想工程师多次修复都没有解决,我自己发现不是...{原创文章,未经允许请勿转载}{原创文章,未经允许请勿转载}{原创文章,未经允许请勿转载}
1. 煤矿生产效率提升:文章讲述了在纳林庙煤矿2号井通过改进桥式转载机输送带的转弯装置,实现了煤矿生产效率的提升。这表明通过技术改进可以有效优化生产过程,减少机械故障和物料运输时间。 2. 桥式转载机的定义...
E酷CMS(EekkuCMS)是一种小型站点内容管理系统,亦可做个人博客(主页)系统,内含文章、图片、留言等基本功能,轻盈小巧,简便易用,是您建小型站点的明智选择!其功能有: 本系统是采用 ASP Access 技术实现...
【标题】"CDSN文章下载并转换为Markdown格式"是一个工具类项目,旨在帮助用户方便地获取并整理CDSN(Chinese Developers Social Network)上的技术文章。这个工具利用了Jsoup库,一个强大的Java库,用于处理HTML和...
根据文章提及的统计数据,不同型号的自移式转载机其处理能力从400吨每小时至12300吨每小时不等,挖掘深度在26米至114米之间,带式输送机的宽度在1.0米到2.2米之间,自移式转载机的移动距离可达0至25米。这些数据反映...
文章中提到的“对称性破缺”是指结构不再具有完美的对称性,这种破坏对于金纳米多层球壳结构的光学特性具有重要的影响。 当金纳米多层球壳结构的对称性遭到破坏时,会产生几个显著的变化:首先,消光峰会表现出对...
文章关键词提取是自然语言处理(NLP)领域的一项关键技术,主要目的是从文本中识别出最具代表性和信息量的词汇或短语,以便概括文章主题、支持搜索引擎优化(SEO)、进行文本分类或信息检索等。这款名为"文章关键词...
E酷CMS(EekkuCMS)是一种小型站点内容管理系统,亦可做个人博客(主页)系统,内含文章、图片、留言、评论等基本功能,轻盈小巧,简便易用,是您建小型站点的明智选择!其功能有: 1、本系统是采用 ASP Access ...