存档在 2013年8月

快慢指针求单链表环

2013年8月30日

问题描述:在单向链表中,每个结点都包含一个指向下一个结点的指针,最后一个结点的这个指针被设置为空。但如果把最后一个结点的指针指向链表中存在的某个结点,就会形成一个环,在顺序遍历链表的时候,程序就会陷入死循环。如下即为一个带环的单链表。link_circle
      如何检测一个链表中是否有环,如果检测到环,如何确定环的入口点(即求出环长,环前面的链长)。
      想象一下在跑道上跑步:两个速度不同的人在操场跑道上一圈一圈地跑,他们总会有相遇的时候。因此我们只需要准备两个指针,同时从链表头出发,一个每次往前走一步,另一个每次往前走两步。如果链表没有环,那么经过一段时间,第二个(速度较快的)指针就会到达终点;但如果链表中有环,两个指针就会在环里转圈,并会在某个时刻相遇。
     大家也许会问,这两个指针要在环里转多少圈才能相遇呢?会不会转几千几万圈都无法相遇?
     实际上,第一个(速度慢的)指针在环里转满一圈之前,两个指针必然相遇。不妨设环长为L,第一个指针P1第一次进入环时,第二个指针P2在P1前方第a个结点处(0 < a < L),设经过x次移动后两个指针相遇,那么应该有x = a + 2x (mod L)[因为P1刚进入环,P2已经在环中移动了a步,那么P1在环里移动x步(P1还没有完成一圈)后,P2则应该在环里共移动了2*x+a步,这个2*x+a可能是p2已经遍历该环很多次],由x = a + 2x (mod L)
      当P2未完成一圈时,x = -a;
      当P2已经超出一圈时,x = L-a;
      显然x = L-a即可满足。
     下面这张图可以清晰地表明这种关系,经过x = L-a次移动,P1向前移动了L-a个位置(相当于后退了a),到达P1′处,而P2向前移动了2L-2a个位置(相当于后退了2a),到达P2′处,显然P1′和P2′是同一点。故在P1还未走满一周时,两快慢指针即可相遇。

two_pointers_in_ring

       在知道链表内有环后,求环长是一件非常简单的事情,只要从刚才那个相遇点开始,固定P2,继续移动P1,直到P1与P2再次相遇,所经过的步数就是环长。

       怎么求环前面那段子链的长度呢?很简单,有两种方法:

       1.让P1和P2都回到链表起点,然后让P2先往前走L次(每次往前走一步),然后P1和P2再同时往前走,当它们再次相遇时,P1所走的步数就是环前面的子链长度。道理很简单:设链的总长度为m,那么前边的子链长度为m-l,所以让指针P2先走L次,则剩下m-l次就可以到达环的相遇点,而P1距离环的相遇点距离也为m-l.

      2.让P2固定在相遇点,P1回到链表头,两指针同时移动直到相遇时即为环的入口,而且P1移动的次数即为子链长度。道理也很简单,由上边的图可以知道,快慢指针相遇时,慢指针在环里移动了L-a步(或者认为后退了a步),也即是再移动a步就可以到达环的入口。另外如图当P1最开始进入环时,P2已经在环内移动了a步,我们知道p2移动的距离是P1移动距离的两倍,所以子链的长度即为a。

面向对象static与面向过程static

2013年8月29日

面向过程static

  1. static修饰的变量。

    1.1 static修饰的全局变量。
        全局变量默认初始化为0;
        static修饰的全局变量放在全局数据区(也是内存的一个区域,在使用前也需要分配);
        static修饰的全局变量只在声明它的文件可见,其他文件不可见。
    1.2 static修饰的局部变量;
       static修饰的局部变量放在全局数据区;
       static修饰的局部变量作用于在于定义他的局部作用域;
      静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
       默认初始化为0.

  2. static修饰的函数

    2.1 static修饰的函数作用域仅仅在声明它的文件可见,其他文件不可见;

面向对象的static

  1. static修饰的类数据成员

    static修饰的数据成员受public,private,protected限制;
    static修饰的数据成员所有对象共享一个副本;
    static修饰的数据成员访问时可以使用对象.来访问,或者类::类访问;
    static修饰的数据成员初始化在类外,定义时需要写明类型,所属类,无需加static

    • 静态数据成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式为:
      <数据类型><类名>::<静态数据成员名>=<值>
    • 类的静态数据成员有两种访问形式:
      <类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>
  2. static修饰类的成员函数

    同样受访问权限保护;
    只能访问类的static数据成员,或者调用类的static成员函数;
    函数参数没有隐含的this指针;
    访问规则,使用.,->,::;
    <类名>::<静态成员函数名>(<参数表>)
    定义时无需再加static修饰。

按a~z,aa~az,ba~bz…za…zz…aaa…aaz,aba~abz…这样的方法进行编号之类问题

2013年8月29日

文件按a~z,aa~az,ba~bz…za…zz…aaa…aaz,aba~abz…这样的方法进行编号。给定任意一个编号,输出文件是第几个文件。
把这些字符串当做26进制数即可:
a–>1
z–>26;
aa–>27
需要做的工作即是进行26进制到10进制的转换。

#include <iostream>
#include <math.h>
using namespace std;

int charToNum(char ch)
{
	return ch - 96;
}
int anyBinaryToDecimal(string num,int binary)
{
	int len = num.size();
	int decimal_num = 0;
	for(int i = 0;i < len; i++)
	{
		decimal_num+=static_cast<int>(charToNum(num[i]) * pow(static_cast<float>(binary),(int)(len - i - 1)));
	}
	return decimal_num;
}

int main()
{
	cout<<anyBinaryToDecimal("aa",26)<<endl;
	system("pause");
}

并发的错觉[美文转载]

2013年8月29日

cpubrain

  今天聊一聊电脑和人脑的并发问题。

  在计算机发展初期,CPU的计算能力非常有限,计算资源稀缺而昂贵。最早的时候一个CPU只能同时运行一个任务,这简直让人无法忍受。什么叫做只能运行一个程序呢?这就像大学上自习占座一样,一旦一本书、一张纸、一个包或一个活人占有了那个桌子,其他人就再也没法用了,无论是这个人出去上厕所,踢球,你都不能去用那个座位,如果你贼胆包天敢偷着去坐,这时候就会有个神秘人突然拍拍你的肩膀告诉你「童靴,这里有人」,这就是常说的「见鬼的故事」。故事里的座位就是CPU,无论当前任务在使用CPU进行计算,还是在读写磁盘IO或进行网络交互,丫都得占着CPU,黑客极客和各种无证程序员们觉得,这,不,科,学!

  于是大家试图通过各种方式来改变这一现象。首先出场的是多通道程序,程序员们很快写了一个监控程序,发现当前任务不用CPU计算时,就唤醒其他等待CPU资源的程序,让CPU资源能够得到充分利用。但多通道的问题是调度乏力,不分青红皂白和轻重缓急,不管是急诊还是普通门诊,该等都得等。

  第二出场的是分时系统,分时系统是一种协作模式,每个程序运行一小段时间都得主动把CPU让出来给其他程序,这样每个程序都有机会用到CPU一小段时间。这时操作系统的监控程序也完善了一些,能够处理相对复杂的请求。早期的Windows和Mac OS(注意没有X)都是采用这种方式来调度程序的。分时系统的问题是,一旦某个程序死循环,系统就没招了,只能干等着,就像死机了一模一样,程序员们说,这是不可接受的!

  第三个隆重登场的是多任务系统,程序员们让操作系统接管了所有的硬件资源,变得更加高级智能,系统进程开始分级,有的是特权级别,有的是平民级别(你就知道,在计算机世界都特么是这个样子!),所有的应用程序以进程和线程方式运行,CPU的分配方式采用了抢占式,就是说操作系统可以强制把CPU的资源分配给目前最需要的程序。程序员们成功了,几乎完美的控制了一切,并造成了很多任务都在同时运行的假象,如果用两个字来形容的话,那就是「和谐」!目前OS X、Unix、Linux、Windows都是采用这种方式进行任务管理的。

  以上都是单核单CPU的情况,但无论线程间的切换多么快,这些都是并发,而不是并行。

好吧,中间插播一段并发和并行的区别。
并发的英文单词是Concurrency,并行是Parallelism。
如果一个系统支持两个或多个动作(Action)同时存在,那就是一个并发系统。
如果一个系统支持两个或多个动作同时执行,那就是一个并行系统。
也就是说,单个CPU永远无法同时执行两个或以上的任务,但是允许任务同时存在。
所以,只有多核或多个CPU才可能发生并行,如果单核单CPU只能发生并发行为。
如果有人以为单核单CPU的并发就是同时执行很多任务,那么这是个错觉。

  不知道解释清楚了木有。插播完毕!

  终于,多核CPU和分布式系统被干出来了,一台计算机可以拥有多颗CPU,每颗CPU可以有多核,同时,成千上万台的机器被连接在一起进行计算,大家一看都晕了,史称「云计算」。随着硬件的变化,软件技术同时开始革新,各种语言开始支持并行计算,比如Erlang/Scala的Actor&Message模型,Go语言的goroutine机制,Java的ForkJoinPool,Objective-C的Grand Central Dispatch技术,当然还有Hadoop等分布式框架。

  总之,到了目前这个阶段,无论是并发,还是并行,计算机和CPU都算是解放了,它们不仅在单台机器上可以执行并行计算,在横向扩展上也变得随心所欲,各种云平台应运而生,公有云私有云混合云balabala,反正是比较晕……

  人脑就比较惨了,在电脑突飞猛进的这几十年里,几乎没有任何进展,脑袋仍然只有一个,也没有裂变出多核……

  上文书谈了电脑的并发和并行的事情,有读者反馈,像一个有趣的教科书!我特么最烦教科书,就因为教科书,哥写了几年程序才把这些事捋清楚,为了让你们不再重蹈覆辙,我容易吗我!

  好,下面我们谈一下人脑的并发,先看一个读者反馈,你们感受一下:

看过一个关于人脑的理论,说不清是并发还是异步。有时候我们很努力的想一个问题,但却怎么也想不起来,于是我们放弃了。但是大脑并没有放弃,此时它会自动起一个gorouting,继续在大脑的各个角落去寻找这个记忆碎片,当找到时执行回调告诉你。而此时你可能正边洗澡边哼着小曲儿!

  关于人脑的机制,其复杂程度超过CPU何止万倍,比如上古奇人周伯通郭靖小龙女的双手互搏到底是并发还是并行呢,Mac君万不敢断言,未来还是让研究人脑图谱的人去探索其真正的奥秘吧。我们在这篇文章中把「一心二用」或「一心多用」统称为人脑的并发。

  俗话说「一心不能二用」,这句话常常送给那些做事三心二意的人,但是我们真的不能一心多用吗?或者说并发带给我们的到底是效率的提升还是状态的下降?关于这件事Mac君的看法是,不可一概而论。「好吧,那位同学请把砖头继续放入怀中,我们还没有讲完」。

  关于人脑的多任务处理,应该从个人特点、所处环境和任务特性来考虑。

  其实人脑天生就是用来处理多任务的,比如你可以一边洗澡一边唱歌,一边看电影一边磕瓜子还要注意不要被飞来的砖头砸到等等,不过这样的多任务都是在放松环境下的简单任务,对我们提升效率没什么意义。

  但是,当我们在健身房跑步时听英语,写文章或编码的时候听歌(所有不让听音乐编程的公司都将死于心碎),坐地铁的时候阅读,步行的时候思考,这就变得非常有意义的,因为我们在一个相对宽松的环境下把复杂的逻辑任务和简单的机械任务结合在一起,既不影响A,也不会干扰B,这种情况是我们优先要采取的并发策略。

  类似的事情,比如开车时听英语,就要因人而异了。我有近10年的驾驶经验,喜欢开车,驾驶基本上已经形成下意识的动作,从出发到目的地往往不会记得自己做了哪些操作,所以我经常开车时听英语并有所收获。但有些人开车仅仅是驾驶已经够紧张忙乱了,倒一次车能车头入绝不车尾进,开次长途出的汗够洗澡的,那么就专心开车好了,车内最好保持安静或听一些舒缓的音乐。

  我曾经看过一本叫做《错觉》的书,书中有一段描述了一位机长在飞机飞行的过程中发现机上设备出了点小故障,于是他和副机长一起排查,接着又找来机械师,哥三忙的不亦乐乎,过了一段时间,有人问,谁在开飞机呢?这时飞机无人驾驶已经很久了,等反应过来之后,飞机已经开始俯冲坠地,机上人员全部罹难!这种空难并不是意外,一架状况良好的飞机直接撞向地面不是偶尔发生,这种现象在航空领域被称作「可控飞行撞地」,其根本原因就是,人们太相信自己的多任务处理能力!

  驾车虽然比驾驶飞机简单多了,但同样是一项非常危险的工作,所以我建议大家,听听音乐就好,另外千万别玩手机。

  还有一种情况就是,在同一时间做两项或多项复杂任务,比如你让程序员在编码的同时帮助别人解决问题,能不能做好?也许有人可以,但我的感觉是,这种安排效率反而会打折扣。 人们在很多时候会低估自己的能力,但在更多时候会高估自己。在复杂任务并发处理的时候,人脑往往会高估自己的处理能力,以为可以,其实任务的并行,上下文的切换,注意力的分散,都会让你的效率大打折扣,所以设计模式中的职责单一原则不是盖的,一个类尽可能只做一件事情,无论是效率还是后期维护都会好很多,人脑其实也是一样。

  总结一下:

  1. 简单任务的并发是大脑天生的nature,每个人都不在不自觉的应用。
  2. 在宽松的环境中让简单机械的任务和复杂有机的任务并行完成是非常不错的做法,提高效率节省时间。
  3. 在高危环境中(驾驶、高空作业等等)我们应该专心致志的只做当前的工作。
  4. 对于复杂任务,我们最好一件一件完成,即使有些人能够同时处理多重任务,那也需要长期的艰苦训练,比如郭靖君,你能否做到,就得看有没有周伯通那样的大哥!

  后记:

  今天给大家介绍一个命令来隐藏文件和文件夹,比如你不想在桌面上看到那么多文件和图标,或者不想让别人看到,只需要打开终端输入如下命令:

  chflags hidden ~/Desktop/*

  想恢复原状:

  chflags nohidden ~/Desktop/*

字符串匹配KMP算法

2013年8月29日

字符串匹配是计算机的基本任务之一。

  举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”?

许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一。它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth。

 这种算法不太容易理解,网上有很多解释,但读起来都很费劲。直到读到Jake Boxer的文章,我才真正理解这种算法。下面,我用自己的语言,试图写一篇比较好懂的KMP算法解释。

  1.

  首先,字符串”BBC ABCDAB ABCDABCDABDE”的第一个字符与搜索词”ABCDABD”的第一个字符,进行比较。因为B与A不匹配,所以搜索词后移一位。

  2.

  因为B与A不匹配,搜索词再往后移。

  3.

  就这样,直到字符串有一个字符,与搜索词的第一个字符相同为止。

  4.

  接着比较字符串和搜索词的下一个字符,还是相同。

  5.

  直到字符串有一个字符,与搜索词对应的字符不相同为止。

  6.

  这时,最自然的反应是,将搜索词整个后移一位,再从头逐个比较。这样做虽然可行,但是效率很差,因为你要把”搜索位置”移到已经比较过的位置,重比一遍。

  7.

  一个基本事实是,当空格与D不匹配时,你其实知道前面六个字符是”ABCDAB”。KMP算法的想法是,设法利用这个已知信息,不要把”搜索位置”移回已经比较过的位置,继续把它向后移,这样就提高了效率。

  8.

  怎么做到这一点呢?可以针对搜索词,算出一张《部分匹配表》(Partial Match Table)。这张表是如何产生的,后面再介绍,这里只要会用就可以了。

  9.

  已知空格与D不匹配时,前面六个字符”ABCDAB”是匹配的。查表可知,最后一个匹配字符B对应的”部分匹配值”为2,因此按照下面的公式算出向后移动的位数:

  移动位数 = 已匹配的字符数 – 对应的部分匹配值

  因为 6 – 2 等于4,所以将搜索词向后移动4位。

  10.

  因为空格与C不匹配,搜索词还要继续往后移。这时,已匹配的字符数为2(”AB”),对应的”部分匹配值”为0。所以,移动位数 = 2 – 0,结果为 2,于是将搜索词向后移2位。

  11.

  因为空格与A不匹配,继续后移一位。

  12.

  逐位比较,直到发现C与D不匹配。于是,移动位数 = 6 – 2,继续将搜索词向后移动4位。

  13.

  逐位比较,直到搜索词的最后一位,发现完全匹配,于是搜索完成。如果还要继续搜索(即找出全部匹配),移动位数 = 7 – 0,再将搜索词向后移动7位,这里就不再重复了。

  14.

  下面介绍《部分匹配表》是如何产生的。

  首先,要了解两个概念:”前缀”和”后缀”。 “前缀”指除了最后一个字符以外,一个字符串的全部头部组合;”后缀”指除了第一个字符以外,一个字符串的全部尾部组合。

  15.

  ”部分匹配值”就是”前缀”和”后缀”的最长的共有元素的长度。以”ABCDABD”为例,

  - ”A”的前缀和后缀都为空集,共有元素的长度为0;

  - ”AB”的前缀为[A],后缀为[B],共有元素的长度为0;

  - ”ABC”的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;

  - ”ABCD”的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;

  - ”ABCDA”的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为”A”,长度为1;

  - ”ABCDAB”的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为”AB”,长度为2;

  - ”ABCDABD”的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。

  16.

  ”部分匹配”的实质是,有时候,字符串头部和尾部会有重复。比如,”ABCDAB”之中有两个”AB”,那么它的”部分匹配值”就是2(”AB”的长度)。搜索词移动的时候,第一个”AB”向后移动4位(字符串长度-部分匹配值),就可以来到第二个”AB”的位置。

类型转换一些细节

2013年8月28日

已知:signed char a = 0xe0,unsigned char b = a, unsigned int c = a;
那么a在内存中的二进制形式为:1110 0000,同理b在内存中也是为1110 0000,同理c的一个字节也为1110 0000;

对于a来说,得知它为一个负数。所以a的值为224 – 256 = -32;
对于b来说,得知它为一个正数,所以b的值为224
对于c来说,因为a的值为-32,所以c的值应该为224 – 2^32 = 0xffffffe0(hex).

fedora通过命令行配置无线,并开机自动连接

2013年8月28日

自动连接无线的命令写到一个脚本文件里,开机自动运行。

以前一直不能通过命令行启用无线,后来才发现是因为NetworkManager服务的原因,禁止该服务后可以通过命令行配置无线正常连网。最好把rpm -e NetworkManager 卸载掉这个NM包,以免它的干扰。

无线使用最简单的wep加密,在路由器上限制了允许mac地址,因此无线安全不是大问题。

无线配置命令非常简单
iwconfig wlan0 essid "[无线AP名称]" key s:[无线密码]
ifconfig wlan up
dhclient wlan0

将写入一个文件,保存为/root/script/start-wlan.sh,也可以保存到其它目录里。

在文件/etc/rc.d/rc.local 里加入一行

.  /root/script/start-wlan.sh

即可

shell科普和一些不为人知的技巧

2013年8月28日
Shell也叫做命令行界面,它是unix操作系统下用户和计算机的交互界面。Shell这个词是指操作系统中提供访问内核服务的程序。

这篇文章向大家介绍Shell一些非广为人知、但却实用有趣的知识,权当品尝shell主食后的甜点吧。

科普

先科普几个你可能不知道的事实:

  • Shell几乎是和Unix操作系统一起诞生,第一个Unix Shell是肯·汤普逊(Ken Thompson)以Multics上的Shell为模范在1971年改写而成,并命名Thompson sh。即便是后来流行的bash(shell的一种变体),它的年龄实际上比当前流行的所有的Linux kernel都大,可谓在Linux系统上是先有Shell再有Kernel。
  • 当前绝大部分unix和MacOS操作系统里的默认的Shell都是bash,bash由Brian Fox在1987年创造,全称Bourne Again shell ( bash)。
  • 你或许听说除了bash之外,还有Bourne shell ( sh),Korn shell ( ksh),C shell (包括 csh and tcsh),但是你知道这个星球上一共存在着大约50多种不同的shell么?想了解他们,请参考 http://www.freebsd.org/ports/shells.html
  • 每个月tiobe上都会给一个编程语言的排名,来显示各种语言的流行度。排名指数综合了全球范围内使用该语言的工程师人数、教学的课程数和第三方供应商数。截止至2012年11月份,tiobe公布的编程语言排行榜里,bash的指数是0.56%排名22位。如果算上它旗下的awk 0.21%和tcl 0.146%,大概就能排到14名。注意这里还不包括bash的同源的兄弟姐妹csh、ksh等,算上它们,shell家族有望接近前十。值得一提的是一直以来shell的排名就很稳定,不像某些“暴发户”语言,比如objective-c,这些语言的流行完全是因为当前Apple系的崛起,但这种热潮极有可能来得快去得更快。
  1. Tiobe下全球编程语言排名1~20

Tiobe下全球编程语言排名21~40

全球最大的源代码仓库Github里,shell相关的项目数占到了8%,跻身前5和Java相当,可见在实战工程里,shell可谓宝刀不老。图片来源,参见这里

  1. Github里源代码项目按编程语言排名

一些强大的命令

再分享一些可能你不知道的shell用法和脚本,简单&强大!

在阅读以下部分前,强烈建议读者打开一个shell实验,这些都不是shell教科书里的大路货哦:)

  • !$
    !$是一个特殊的环境变量,它代表了上一个命令的最后一个字符串。如:你可能会这样:
    $mkdir mydir
    $mv mydir yourdir

    $cd yourdir
    可以改成:
    $mkdir mydir
    $mv !$ yourdir
    $cd !$
  • sudo !!
    以root的身份执行上一条命令 。
    场景举例:比如Ubuntu里用apt-get安装软件包的时候是需要root身份的,我们经常会忘记在apt-get前加sudo。每次不得不加上sudo再重新键入这行命令,这时可以很方便的用sudo !!完事。
    (注:在shell下,有时候你会输入很长的命令,你可以使用!xxx来重复最近的一次命令,比如,你以前输入过,vi /where/the/file/is, 下次你可以使用 !vi 重得上次最近一次的vi命令。)
  • cd –
    回到上一次的目录 。
    场景举例:当前目录为/home/a,用cd ../b切换到/home/b。这时可以通过反复执行cd –命令在/home/a/home/b之间来回方便的切换。
    (注:cd ~ 是回到自己的Home目录,cd ~user,是进入某个用户的Home目录)
  • ‘ALT+.’ or ‘<ESC> .’
    热建alt+. 或 esc+. 可以把上次命令行的参数给重复出来。
  • ^old^new
    替换前一条命令里的部分字符串。
    场景:echo "wanderful",其实是想输出echo "wonderful"。只需要^a^o就行了,对很长的命令的错误拼写有很大的帮助。(注:也可以使用 !!:gs/old/new
  • du -s * | sort -n | tail
    列出当前目录里最大的10个文件。
  • :w !sudo tee %
    在vi中保存一个只有root可以写的文件
  • date -d@1234567890
    时间截转时间
  • > file.txt
    创建一个空文件,比touch短。
  • mtr coolshell.cn
    mtr命令比traceroute要好。
  • 在命令行前加空格,该命令不会进入history里。
  • echo “ls -l” | at midnight
    在某个时间运行某个命令。
  • curl -u user:pass -d status=”Tweeting from the shell” http://twitter.com/statuses/update.xml
    命令行的方式更新twitter。
  • curl -u username –silent “https://mail.google.com/mail/feed/atom” | perl -ne ‘print “\t” if /<name>/; print “$2\n” if /<(title|name)>(.*)<\/\1>/;’
    检查你的gmail未读邮件
  • ps aux | sort -nk +4 | tail
    列出头十个最耗内存的进程
  • man ascii
    显示ascii码表。
    场景:忘记ascii码表的时候还需要google么?尤其在天朝网络如此“顺畅”的情况下,就更麻烦在GWF多应用一次规则了,直接用本地的man ascii吧。
  • ctrl-x e
    快速启动你的默认编辑器(由变量$EDITOR设置)。
  • netstat –tlnp
    列出本机进程监听的端口号。(注:netstat -anop 可以显示侦听在这个端口号的进程)
  • tail -f /path/to/file.log | sed '/^Finished: SUCCESS$/ q'
    当file.log里出现Finished: SUCCESS时候就退出tail,这个命令用于实时监控并过滤log是否出现了某条记录。
  • ssh user@server bash < /path/to/local/script.sh
    在远程机器上运行一段脚本。这条命令最大的好处就是不用把脚本拷到远程机器上。
  • ssh user@host cat /path/to/remotefile | diff /path/to/localfile –
    比较一个远程文件和一个本地文件
  • net rpc shutdown -I ipAddressOfWindowsPC -U username%password
    远程关闭一台Windows的机器
  • screen -d -m -S some_name ping my_router
    后台运行一段不终止的程序,并可以随时查看它的状态。-d -m参数启动“分离”模式,-S指定了一个session的标识。可以通过-R命令来重新“挂载”一个标识的session。更多细节请参考screen用法 man screen
  • wget --random-wait -r -p -e robots=off -U mozilla http://www.example.com
    下载整个www.example.com网站。(注:别太过分,大部分网站都有防爬功能了:))
  • curl ifconfig.me
    当你的机器在内网的时候,可以通过这个命令查看外网的IP。
  • convert input.png -gravity NorthWest -background transparent -extent 720×200  output.png
    改一下图片的大小尺寸
  • lsof –i
    实时查看本机网络服务的活动状态。
  • vim scp://username@host//path/to/somefile
    vim一个远程文件
  • python -m SimpleHTTPServer
    一句话实现一个HTTP服务,把当前目录设为HTTP服务目录,可以通过http://localhost:8000访问 这也许是这个星球上最简单的HTTP服务器的实现了。
  • history | awk '{CMD[$2]++;count++;} END { for (a in CMD )print CMD[a] " " CMD[a]/count*100 "% " a }' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n10
    (注:有点复杂了,history|awk ‘{print $2}’|awk ‘BEGIN {FS=”|”} {print $1}’|sort|uniq -c|sort -rn|head -10)
    这行脚本能输出你最常用的十条命令,由此甚至可以洞察你是一个什么类型的程序员。
  • tr -c “[:digit:]” ” ” < /dev/urandom | dd cbs=$COLUMNS conv=unblock | GREP_COLOR=”1;32″ grep –color -e “[^ ]” –
    想看看Marix的屏幕效果吗?(不是很像,但也很Cool!)