Tuesday, December 21, 2010

[Linux]同步ubuntu上的时间

$ sudo aptitude install rdate
$ sudo rdate -s clock-1.cs.cmu.edu
$ sudo hwclock --systohc 

[Emacs]在Emacs中使用gdb

在Emacs中使用gdb调试程序 (推荐)
http://www.inet.net.nz/~nickrob/
An Introduction To Using GDB Under Emacs


1 M-x gdb 回车

2 Run gdb (like this): gdb --annotate=3 myprogname 回车
如果使用的是emacs 23.1 比如ubuntu 10.10当中的emacs-snapshot, 如下
Run gdb (like this): gdb -i=mi myprogname 回车

Gud->GDB-MI->Display other windows

Tuesday, November 16, 2010

[Python]String的decode, encode

string的decode用法:
str.decode(encoding="gb2312",errors="strict"
在这里我们告诉python解释器用encoding参数所指定的来对str解码.标准的encoding可以查看这里

和简体中文相关的通常有gb2312,gb18030以及gbk(大多数BBS的中文encoding)

一篇参考http://hi.baidu.com/tornadory/blog/item/2fa5f0c36cf7bd5fb219a801.html

[Linux]Profiling

gprof

gprof是GNU的profiling工具,使用的时候需要编译期的支持
使用:
1 编译:时需要使用"-pg"选项
$cc -g -c myprog.c utils.c -pg
$cc -o myprog myprog.o utils.o -pg
如果加上了"-g"选项(如上),则可以支持Line-by-line Profiling
2 运行: 执行生成的可执行文件(比如上面的myprof), 这时会生成一个"gmon.out"的文件
3 查看: 用gprof 查看profiling结果
$gprof myprof | more
参考:
gprof Quick-Start Guide

perf

perf是Linux下非常强大的profiling工具,也非常好用.
perf类似于git那样,有一堆子命令,比较常用的有record,report,annotate,stat等.
运行一个程序foo并记录下profile(默认为perf.data):
$ sudo perf record ./foo
读取刚才生成的profile结果(默认perf.data)并显示分析结果:
$ sudo perf report
输出结果类似
    49.97%  foo  filter_bench         [.] main
     5.31%  foo  libc-2.12.1.so       [.] 0x7aeab
     0.36%  foo  libstdc++.so.6.0.15  [.] operator new[](unsigned long)
注意这里libc-2.12.1.so中的symbol没有被load进来,所以无法显示具体的函数名而只能看见一个入口地址0x7aeab.
在ubuntu/debian上你可以安装libc6-dbg(注意不是libc6-dev)帮助gdb,perf这样的工具traceback.libc6-dbg包含了libc6的debug信息
$ apt-get install libc6-dbg
显示annotated code
$ sudo perf annotate
运行一个命令并查看硬件counter:
$ perf stat --repeat 10 -e cycles:u \
-e instructions:u -e l1-dcache-loads:u -e l1-dcache-load-misses:u ./foo
查看所有支持的硬件counter:
$ perf list
参考:
Linux kernel profiling with perf

OProfile

OProfile利用硬件支持来profile系统或者application. 与gprof不同,OProfile不会在binary中添加指令
启动:
1 加载oprofile
$sudo opcontrol --init
2 设置是否需要profile kernel,如果需要
$sudo opcontrol --vmlinux=/boot/vmlinux-`uname -r`
如果不需要
$sudo opcontrol --no-vmlinux
3 开始采集数据
$sudo opcontrol --start 
Using default event: CPU_CLK_UNHALTED:100000:0:1:1
Using 2.6+ OProfile kernel interface.
Using log file /home/apc999/tempsession/samples/oprofiled.log
Daemon started.
Profiler running.
4 查看oprofile状态
$sudo opcontrol --status
Daemon running: pid 13892
Separate options: none
vmlinux file: none
Image filter: none
Call-graph depth: 0
5 结束采集数据
$sudo opcontrol --stop 
6 结束oprofile daemon
$sudo opcontrol --shutdown 

参考:
OProfile Manual

Sunday, October 31, 2010

[Linux]用gs合并几个pdf文件

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=finished.pdf file1.pdf file2.pdf

Thursday, October 21, 2010

PPT 热键

Press F5 in PowerPoint/Windows or Control-Shift-S in PowerPoint X/Mac to start a slide presentation from the beginning

Press Shift+F5 in PowerPoint 2003 or Control+Shift+B in PowerPoint X/Macintosh to start a presentation from the current slide

Friday, October 15, 2010

手机配置

Apple iPhone 4
  • CPU: Apple A4 - fully compatible with ARM Cortex-A8, running at 1 GHz, 64 L1 Cache, 640 L2 Cache
  • Memory: 512 MB eDRAM
  • Storage: 16 GB or 32 GB flash memory
Nokia N900
  • CPU: ARM Cortex-A8, running at 600 MHz
  • Memory: 256 MB
  • Storage: 32 GB internal; Expandable to up to 48 GB with an external microSD card

Thursday, October 14, 2010

Cocoa编程笔记(update中)

Cocoa是Mac上使用的图形界面framework, 简单说来就是一个库使开发人员可以定制自己的基于GUI的 Application。Cocoa使用的语言是Object-C(参见我的Object-C笔记)。 Cocoa编程的学习曲线比其他GUI编程的要陡,因为有很多概念要理解。我在学习过程中,参照如下的一些tutorial或者文档:

Cocoa Fundamental Guide:这是最核心最基础的文档。介绍了最重要的概念

Cocoa Event Handling:Cocoa中如何处理事件

Introduction to Text System User Interface Layer,介绍了比如如何programatically 创建一个NSTextView,添加至NSScrollView,如何调整Text边距等等.

Introduction to Text Editing Programming Guide for Cocoa, 介绍如何使用Cocoa的Text System来完成编辑工作,比如key binding, 如何delegate message等.

一个简单界面的Cocoa Application:最最简单的一个Application.如果想学习一个最简单的Cocoa Application,从这个文档看起.

Model-View-Control模型

Cocoa中广泛使用了MVC这种的Design Pattern,把一个application功能分解为如下三个部分:

Model objects: 负责逻辑处理,不直接和用户界面打交道
View objects: 用户界面.比如label, textfield等
Controller objects: 连结Model和View, 比如处理界面送来的用户action,应用后台逻辑做出update等


内存管理
alloc, init, dealloc, retain, release, autorelease. 所有从NSObject继承而来的类都有这些方法,这些涉及到内存管理.

alloc: 从内存中分配一块内存,但仅仅是获得一块内存空间,未作任何初始化
init:初始化一个类,类似于C++中的构造函数,一般和alloc配合使用:
id  myObject = [[NSString alloc] init];
dealloc: 销毁一个类,释放内存空间
[myObject dealloc];
retain: 将一个对象的引用计数加1
[myObject retain];
release: 将一个对象的引用计数减1
[myObject release];
autorelease:每当一个对象得到autorelease消息,这个对象就将被添加到autorelease pool当中. 当改eventloop结束时,所有autorelease pool当中的对象将被release.通常一个method要返回一个对象的时候,autorelease这个对象是个好主意.
- (NSString)autoreleasedString
{
  NSString *string = [[NSString alloc] initWithString:
      @"The Sender of this message will never see this string…"];
  [string autorelease]; // we have to do this or we'll get a memory leak
  return string;
}


神秘的IBAction和IBOutlet?

经过预处理以后,IBAction实际上就是void而IBOutlet实际上根本就是一个空的宏(见定义在NSNibDeclarations.h).它们的作用是在于作为一种syntax sugar,提醒Interface Builder,"嗨,这几个被我修饰的变量或者函数是你应该知道的~".



事件处理(Event Handling)
有两种Message: 由外部设备比如键盘或者鼠标发起的Event message,以及由其他对象发起的Action message.

Event message 通常已知,所以NSResponder提供了声明以及缺省的实现.
NSResponder是一个抽象类.而Cocoa中最核心的三个类NSApplication, NSWindow, 以及 NSView都继承了NSResponder.

比如我们要处理mouseDown这个事件,我们可以继承一个NSView类(或者NSView的子类,比如NSTextView,NSTabView),然后重载mouseDown:这个方法。如果一个NSWindow上有多个NSView(或其子类), 则应该重载最上面的View,否则盖在底下的不能接受到该消息

- (void)mouseDown:(NSEvent *)theEvent {
    // determine if I handle theEvent
    // if not...
    [super mouseDown:theEvent];
}


Delegate
Common mistakes with delegation in Cocoa
一个在NSImageView中delegate mouseDown等消息的例子:
http://it.toolbox.com/blogs/macsploitation/adding-delegates-to-nsviews-21138

Text System
NSTextStorage 是NSMutableAttributedString的子类. 一般作为NSTextView 的text repository. Introduction to Text System Storage Layer Overview

NSTextView 和用户打交道的界面
NSTextContainer:Introduction to Text Layout Programming Guide


NSScrollView: Introduction to Scroll View Programming Guide for Cocoa
NSClipView:


NSParagraphStyle:Introduction to Rulers and Paragraph Styles

一个超级简单的Cocoa Text System Application
HelloWorld.h:
#import 

@interface HelloWorld : NSObject  {
    NSWindow *window;
 
 NSTextStorage *textStorage;
 NSLayoutManager *layoutManager;
 NSTextContainer *textContainer;
 NSTextView *textView;
}

@property (assign) IBOutlet NSWindow *window;

@end
HelloWorld.m
#import "HelloWorld.h"

@implementation HelloWorld

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
 // Insert code here to initialize your application 
 
 //setup textStorge
 textStorage = [[NSTextStorage alloc] initWithString:@"123abcde\n456"];
 
 //setup layoutManager
 layoutManager = [[NSLayoutManager alloc] init]; 
 [textStorage addLayoutManager:layoutManager]; 
 [layoutManager release];
 
 //setup textContainer
 NSRect cFrame = [[window contentView] frame];  
 textContainer = [[NSTextContainer alloc] initWithContainerSize:cFrame.size];
 [layoutManager addTextContainer:textContainer]; 
 [textContainer release];
 
 //setup textView
 textView = [[NSTextView alloc] initWithFrame:cFrame textContainer:textContainer]; 
 [window setContentView:textView]; 
 [window makeKeyAndOrderFront:nil]; 
 [textView release];
}

@end


常用数据结构:
NSArray: 类似list, 不能添加元素
Objective-C Tutorial: NSArray读取index位置的元素
[myArray objectAtIndex:index]

NSMutableArray:一个类似python中list的存在.可以通过addObject:来添加元素.

NSDictionary
NSMutableDictionary:一个类似于python中dict的存在,提供setObject:forKey:和removeObjectForKey:


Do things Programatically

获取中文encoding
http://www.cocoadev.com/index.pl?CharacterEncoding
NSStringEncoding gb18030 = CFStringConvertEncodingToNSStringEncoding 
    (kCFStringEncodingGB_18030_2000);
用中文encoding读文件
[options setObject:absoluteURL
    forKey:NSBaseURLDocumentOption];
[options setObject:[NSNumber numberWithUnsignedInteger:gb18030] 
    forKey:NSCharacterEncodingDocumentOption];
[options setObject:NSPlainTextDocumentType
    forKey:NSDocumentTypeDocumentOption];
 
NSAttributedString *fileContents = [[NSAttributedString alloc]
      initWithURL:absoluteURL options:options 
    documentAttributes:NULL error:outError];
NSTextView背景设为透明
[[textView enclosingScrollView] setDrawsBackground:NO];
[textView setDrawsBackground:NO];
NSImageView显示图片
NSImage *image = [NSImage imageNamed:@"yellow_background.bmp"];
[imageView setImage: image];
给NSTextView和NSTextContainer之间添加空白区域
[myNSTextView setTextContainerInset:NSMakeSize (width, height)];
使用NSLog,NSAssert输出信息,帮助调试
NSLog(@"init, %p, %p",backgroundImage, textView);
NSAssert([myWindow delegate] == self, @"You forgot to connect the window delegate.!");

NSLog 格式化字符串


其他
If you want to name your NSDocument subclass something other than MyDocument (the default name), change the name in Interface Builder and wherever it occurs in the Document header (.h) and implementation (.m) files. You must also change the name under the NSDocumentClass key in the Info.plist file.

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TextArchitecture/Tasks/TextEditor.html#//apple_ref/doc/uid/20001798-CJBHAJJJ

Monday, October 11, 2010

[Math]凑硬币

有6分9分和25分的硬币,不能用这3种硬币凑出来的面值最大是多少

Sol: General problem 叫 Coin Problem

对于这题, 考察面值N分
(1) N = 3k, 当k>1的时候都可以用6和9凑出来
(2) N = 3k + 1, 当k>=10的时候, N-25是3的倍数且大于等于6,可以用(1)得出
(3) N = 3k + 2, 当k>=18的时候, N-50是3的倍数且大于等于6,可以用(1)得出

所以最大不能表出的面值为53

Sunday, October 03, 2010

[Math]扔骰子

Q: 能否重新设计两个六面骰子,每个骰子上是正整数并且两个骰子之和的分布与两个正常骰子之和相同(Is it possible to change the numbers on two six sided dice to other positive numbers so that the probability distribution of their sum remains unchanged?)

Sol: 考虑两个普通骰子之和的分布的generating function:
(x/6+x^2/6+x^3/6+x^4/6+x^5/6+x^6/6)*(x/6+x^2/6+x^3/6+x^4/6+x^5/6+x^6/6)
= (x/6+2*x^2/6+2*x^3/6+x^4/6)*(x/6+x^3/6+x^4/6+x^5/6+x^6/6+x^8/6)

也就是说可以设计第一个骰子的六面为(1,2,2,3,3,4),第二个骰子的六面为(1,3,4,5,6,8)
这样可以满足新的骰子的和的分布和从前相同

Friday, September 24, 2010

[Linux]resize image

比如我有一个image叫old.png想要resize成320x240的文件,可以使用如下命令
convert -geometry  320x240 old.png new.png
注意new.png依然保持了原图片的横宽比例,所以未必能得到你想要的大小, 如果不想保持横宽比例
convert -resize  '320x240!' old.png new.png

[Math]老鼠,毒药和酒

如果你有9瓶酒,其中一瓶有毒但你不知道究竟是哪一瓶.幸运的是你有两只老鼠可以拿来测试--老鼠碰到毒酒立刻就被毒死了.给定这两只老鼠,如果测试两轮(一轮指你可以对部分或者全部老鼠喂一次酒),如何能够测试出哪瓶是毒酒? 进一步,如果给你5只老鼠,如何在两轮内找出243瓶酒中哪一瓶是毒酒.

Sol:
part1
给酒编号,编号为1 2 3的酒喂老鼠A, 编号为3 4 5的酒喂老鼠B.
case1 A alive, B alive -> poised in 6, 7, 8, 9.
case2 A dead, B alive -> poised in 1, 2
case3 A alive, B dead -> poised in 4, 5
case4 A dead, B dead -> poised is 3, done

case1的情况下, 使用A测试6,7, 使用B测试7,8就可以得到最后结果
case2和case3的情况下, 让活着的一只老鼠喝一瓶酒,也可以得到结果.

part2
让我们用N(k,1)指代给定k只老鼠,只能测试一轮的情况下,最多能找出多少瓶酒中的一瓶毒酒.不难发现N(k,1)=2^k (特别的N(0,1)=1 也就是说一只老鼠都不给,只能断定:只有1瓶的时候这瓶一定是毒酒)

N(k,2)=N(k,1)*C(0,k) + N(k-1,1)*C(1,k) + N(k-2,1)*C(2,k) + ... + N(0,1)*C(k,k)
= 3^k
=> N(5,2)=243

Thursday, September 23, 2010

[Python]几个常用数据结构的高效实现

Python中最广为熟知的container就是list和dict了. 但是对于特定的用途, 这二者未必是最高效的.比如判断容器中是否包括x(x in container),如果容器是list就需要O(n)的时间.而使用set的话这个就只需要O(1)的时间. 我的血泪教训是: 在list很长的时候, x in list这个操作是非常非常低效的.一个好的主意是在另一个set容器来保存membership的信息.

集合(Set)
set是Python的built-in类型,对于membership testing, removing duplicates 的操作非常高校(O(1)时间).另外对集合操作也非常方便.如果对容器元素的顺序没有要求,set是非常好的选择对象
>>>s= set()
>>>s.add(1)
>>>s.add(2)
>>>s.remove(1)  #throw exception if not in set
>>>s.discard(1) #remove if present
>>>print set([1,2,3]) | set([3,4,5]) #union
set([1, 2, 3, 4, 5])
>>>print set([1,2,3]) & set([3,4,5]) #intersection
set([1])
>>>print set([1,2,3]) - set([3,4,5]) #difference
set([1, 2])
>>>print set([1,2,3]) ^ set([3,4,5]) #symetric difference
set([1, 2, 4, 5])
栈(Stack)
栈的特点是先进后出(FILO).built-in的list用来实现栈非常合适.对于append和pop的实现非常高效.

FIFO队列(FIFO Queue)
队列的特点是先进先出(FIFO). list用来实现队列不够有效.collections.deque可以弥补这一缺点(fast appends and pops from both ends)
>>>from collections import deque
>>>queue = deque()
>>>queue.append(1)
>>>queue.append(2)
>>>queue.appendleft(3)
>>>print queue
deque([3, 1, 2])
>>>queue.pop()
2
>>>queue.popleft()
3

利用deque,我们可以实现一个时间上高效的FIFO queue:
class FIFOQueue():
    def __init__(self):
        self.queue = deque()
        self.counter = itertools.count(1)    # unique sequence count
        self.task_finder = {}                # mapping of tasks to entries

    def append(self, task):
        if debug:
            print "FIFOQueue.append "+repr(task)

        if task in self:
            return
        count = next(self.counter)

        entry = [count, task]
        self.task_finder[task] = entry
        self.queue.append(entry)
        if debug:
            print "FIFOQueue.append "+repr(task)+" done"

    def top(self):
        if debug:
            print "FIFOQueue.top "
        while self.queue:
            count, task  = self.queue[0]
            if count:
                if debug:
                    print "FIFOQueue.pop "+repr(task)+" done"
                return task
            else:
                self.queue.popleft()
        if debug:
            print "FIFOQueue.top none"
        return None

    def pop(self):
        if debug:
            print "FIFOQueue.pop "
        while not self.top():
            continue
        if self.queue:
            entry  = self.queue.popleft()
            count, task = entry
            assert(count != None)
            assert(self.task_finder[task] == entry)
            del self.task_finder[task]
            if debug:
                print "FIFOQueue.pop "+repr(task)+" done"
            return task
        if debug:
            print "FIFOQueue.pop none"
        return None

    def remove(self, task):
        if debug:
            print "FIFQueue.remove "+repr(task)
        if task not in self:
            return
        entry = self.task_finder[task]
        assert(entry[0] != None)
        entry[0] = None
        del self.task_finder[task]
        if debug:
            print "FIFOQueue.remove "+repr(task)+" done"

    def __len__(self):
        return len(self.task_finder)

    def __contains__(self, task):
        return self.task_finder.has_key(task)

    def __repr__(self):
        return repr(self.queue)
这个实现的好处在于可以常数时间删除一个元素以及在常数时间内判定一个元素是否属于这个queue

优先队列(Priority Queue)
使用堆(heap)实现的优先队列(priority queue)可以在O(1)时间内得到队列中最小元素,O(logn)时间内插入或者删除一个元素.我通常在simulator中会使用priority queue来管理所有事件.

Python提供了heapq来实现.值得注意的是heapq并不是一个容器,而是操作在list上的一系列的heap算法(包括heappush,heappop,heapify)等.http://docs.python.org/library/heapq.html给出了用这一些算法实现堆排序(heapsort)以及优先队列的. 不过在那个优先队列的例子里有一点小bug. 这里是我给出的代码
import itertools
from heapq import heappush, heappop
class PriorityQueue():
    def __init__(self):
        self.pq = []                         # the priority queue list
        self.counter = itertools.count(1)    # unique sequence count
        self.task_finder = {}                # mapping of tasks to entries
        self.size = 0
 
    def add_task(self, priority, task, count=None):
        if count is None:
            count = next(self.counter)
        entry = [priority, count, task]
        self.task_finder[task] = entry
        heappush(self.pq, entry)
        self.size  += 1

    def pop_task(self):
        while self.pq:
            entry = heappop(self.pq)
            priority, count, task = entry
            if self.task_finder[task] == entry:
                del self.task_finder[task]
            if count is not None:
                self.size -= 1
                return (priority, task)
        return None


    def del_task(self, task):
        entry = self.task_finder[task]
        if entry[1] != None:
            self.size -= 1
        entry[1] = None

    def reprioritize(self, priority, task):
        entry = self.task_finder[task]
        self.add_task(priority, task, entry[1])
        if entry[1] != None:
            self.size -= 1
        entry[1] = None

    def __len__(self):
        return self.size

Intel CPU Lineup, roadmap

从Intel的主页来看Processor产品线的划分

按照处理器的品牌

  • Core(酷睿)主要是针对中端到高端的处理器.
    - 早期(2006年)的32位CPU使用NetBurst架构,分为Core Solo(单核)和Core Duo(双核)
    - 升级到64位CPU以后, 使用了Core架构,从低端到高端分为Core 2 Solo, Core 2 Duo, Core 2 Quad和Core 2 Extreme
    - 升级到Nehalem微架构以后, 从低端到高端可以具体划分为Core i3, Core i5, Core i7. i3,i5,i7在不同的时间使用不同的微架构. 这3个系列的区别可见下表
  • Pentium
  • Celeron
  • Atom
  • Xeon(至强), 主要针对服务器以及工作站

按照处理器的微架构
  • Sandy Bridge
  • 在2011年1月份发布. 苹果在2月份就宣布新的Macbook Pro使用基于Sandy Bridge 的i5和i7. 相比上代的Nehalem的Westmere架构,同样为32nm,而这次的革新意义是在于完美的将CPU和GPU真正融合在了一起。64KB L1 Cache (32KB iCache + 32KB dCache) , 256KB L2 Cache per core.与集成的GPU共享L3 Cache
  • Nehalem
  • 2008年9月发布(i7). 重新引入超线程(Hyper Threading)技术使得每一个core可以同时运行2个线程

Intel Microarchitecture 所有Intel Microarchitecture列表 这是从wiki上偷来的图,展示从Netburst和P6到Nehalem的变迁
Intel CPU的家族史: Intel CPU 家族一覽 - 桌上電腦(上篇) Intel CPU 家族一覽 - 桌上電腦(中篇) Intel CPU 家族一覽 - 桌上電腦(下篇)

Monday, September 20, 2010

[Python]glob

glob用于寻找符合pattern的文件名/目录名, 相当于shell下的ls, 很好用
>>import glob
>>glob.glob(”/path/to/me/*.txt”)
['./1.txt', './2.txt']

Monday, September 13, 2010

[Linux]查看系统信息相关命令

Linux版本信息

$uname -a
Linux gs7600 2.6.32-24-generic #42-Ubuntu SMP Fri Aug 20 14:21:58 UTC 2010 x86_64 GNU/Linux

CPU信息


$cat /proc/cpuinfo

Cache大小

cat /sys/devices/system/cpu/cpu0/cache/index*/size
系统内存使用信息

系统当前内存使用状况
$cat /proc/meminfo
或者
$free -m

如果要看具体某个进程的内存使用情况,/proc/pid/底下有一些 比如statm, maps, smaps, status.

mem_usage.py是另一个脚本可以查看具体进城的内存使用. 比如要查看pid为4418的进程
$mem_usage.py 4418
Mapped memory:
               Shared            Private
           Clean    Dirty    Clean    Dirty
    r-xp    8364        0    15484        0  -- Code
    rw-p       0        0        0     1704  -- Data
    r--p     704        0      648      516  -- Read-only data
    ---p       0        0        0        0
    rw-s       0      304        0        0
    r--s     800        0       40        0
   total    9868      304    16172     2220
Anonymous memory:
               Shared            Private
           Clean    Dirty    Clean    Dirty
    rwxp       0        0        0     1340  -- Writable code (stack)
    r-xp       0        0        0        0
    rw-p       0        0        0    81048  -- Data (malloc, mmap)
    ---p       0        0        0        0
   total       0        0        0    82388
   ----------------------------------------
   total    9868      304    16172    84608

更多详细的可以参见http://elinux.org/Runtime_Memory_Measurement

进程的信息

最基本的命令就是广为人知的top.
htop是更fancy的一个版本, 可以看到每个线程使用的内存和CPU

当前mount的设备
$cat /proc/mounts 
或者等同的
$mount

I/O的统计信息

$ iostat
Linux 2.6.38-8-server (fawnserver)  04/15/2011  _x86_64_ (12 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           4.47    0.00    2.07    0.16    0.00   93.30

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               6.24        51.31      1011.76     676334   13337192
sdb               0.00         0.03         0.00        408          0
$ iotop
Total DISK READ: 0.00 B/s | Total DISK WRITE: 0.00 B/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                                       
    1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % init
    2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
    3 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/0]
    4 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kworker/0:0]
...

网络流量的统计信息

每块网卡的收发packet数目:
$cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:896689377 11170911    0    0    0     0          0         0 896689377 11170911    0    0    0     0       0          0
  eth0:708410727 3925021    0    0    0     0          0      5468 84085137  732531    0    0    0     0       0          0

bwm-ng:基于/proc/net/dev信息,动态显示各个网卡的traffic

iftop:动态显示各台主机之间traffic

nethogs: 如果要查看每个process使用的网络情况,可以使用
http://www.ubuntugeek.com/nethogs-net-top-tool-grouping-bandwidth-per-process.html

能耗

如果是基于Intel的CPU, 可以用powertop查看power consumption

内核消息

dmesg将内核消息输出至标准输出
$dmesg

Ref:

http://www.ubuntugeek.com/category/monitoring
http://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html

Thursday, September 09, 2010

[Linux/Mac]删除所有.svn文件夹

用于删除一个目录下(以及其子目录下)所有的.svn目录
$ rm -rf `find . -type d -name .svn`

Monday, July 26, 2010

tbb: Intel® Threading Building Blocks笔记

tbb(Threading Building Blocks)是Intel开发的一个C++模板库, 类似于STL. 其特点是针对对于多核(multi-core)CPU的优化.提高在多线程的环境下程序并发性. tbb提供了多种类似于STL但高度并行的容器类.

安装

Ubuntu:
sudo apt-get install libtbb2 libtbb-dev libtbb-doc
MacOS上:
sudo port install tbb
编译

g++ -ltbb foo.cpp
使用

concurrent_hash_map
此容器是类似于STL中的map的存在. 同std::map一样,concurrent_hash_map为一个从Key类型读取T类型的容器. 为提高并发性,我们需要用accessor或者const_accessor两种不同方式访问此容器的某元素.accessor和const_accessor均为智能指针,其中accessor写和修改访问,会lock相应的key直到访问结束.而const_accessor用于只读方式访问,这样可以同时有多个不同的const_accessor同时指向同一个key.区分不同的访问方式有助于增加程序的并发性.


#include <iostream>
#include <string>
#include <tbb/concurrent_hash_map.h>

using namespace tbb;
using namespace std;
typedef concurrent_hash_map<string,string> CacheTable;

int main() {
    CacheTable cache;

    // insert an element to the map
    CacheTable::accessor a;
    cache.insert(a, s);
    a->second = "value1";
    a.release();
    
    // look for an element in the map
    CacheTable::const_accessor ca;
    if (cache.find(ca, "key1"))
         cout << "the value is " << ca->second << endl;
    else
         cout << "not found" << endl;

    // iterate over the map
    for(CacheTable::const_iterator itr=cache.begin(); itr!=cache.end(); ++itr)
         std::cout << itr->first << " - " << itr->second << std::endl;

}
concurrent_queue
一个类似于stl中queue的存在. 提供包括push(item),pop(item)以及try_pop(item)等等的操作.
下面是对于一个concurrent_queue的iteration操作:
#include <iostream>
typedef concurrent_queue::const_iterator iter;
for(iter i(q.unsafe_begin()); i!=q.unsafe_end(); ++i ) {
   do sth 
}

atomic
如果atomic< your data type> x, 以下操作为原子操作
= x  read the value of x
x =  write the value of x, and return it
x.fetch_and_store(y)  do y=x and return the old value of x
x.fetch_and_add(y)  do x+=y and return the old value of x
x.compare_and_swap(y,z)  if x equals z, then do x=y. In either case, return old value of x

Wednesday, July 21, 2010

git笔记

git是Linus亲自操刀设计实现的版本控制工具(据说Linus在两个礼拜内搞定了git,教主威武).git功能上比SVN要强,但是学习曲线也陡了很多. 这里是我对SVN的笔记


文档

关于git的教程和手册网上很多, 但很多写的都不好.最推荐:
Git Workflow (这里的diagram非常给力)
How to version projects with Git 图文并茂,有木有?
git quick reference

这几个也不错
Git Magic 中文,英文
Pro Git(中文)

其他的还有:
Understanding Git Conceptually
Git User Manual写的比较晦涩
Git - SVN Crash Course. 我觉得帮助不是很大, 因为git和svn在用法上区别是在太大了
GIT cheat sheet这个不错
Basic Branch Merging
关于stash, log, 以及gitconfig的用法

用法

初始化一个workspace
从远端克隆一个repository到本地
$git clone git://path/to/your/git/repo
注意git是一个分布式的版本控制系统. 如果你从server1上clone的repo, 那么以后server1就相当于你的源.如果以后server2再clone了你的repo, 你就相当于server2的源.我发现这种结构很方便调试 -- 在其他机器上可以从我本地repo来pull 文件. clone的时候除了git协议还可以使用ssh, 比如
$git clone ssh://hostname/path/to/your/git/repo

工作流程
进入你的工作目录,通常大家首先将本地repository更新到源上的最新版本(大致相当于svn update, 但是因为git是分布式的设计,更新到源上最新未必是全局最新). 下面的命令从origin 这个remote 更新 master这个branch的update.
$git pull origin master
未必需要从自己所在的branch来更新. 比如你实际在master这个branch, 你也可以更新branch foo的东西,即使你还是留在master这个branch里:
$git pull origin foo
有时候每次都是默认同样的remote同样的branch,那么我们可以修改工作目录下的.git/config文件,
[branch "master"]
    remote = origin
    merge = refs/heads/master
这样就可以直接用下面命令来更新而无须指定remote和branch
$git pull


做了修改后, 为了查看当前工作目录的状态,比如哪些文件被改动, 哪些文件没有commit, 可以使用status (大致相当于svn st)
$git status
如果需要git status的时候忽略某些文件,比如.o文件或者.pyc文件, 我们可以在.gitignore这个文件中加入两行*.o以及*.pyc.

修改了本地的文件后, 需要将其用add命令将其加入index. svn里没有index的概念,而且add这个命令在svn中是将一个文件加入版本控制. 而git里, 一个文件每次的修改都会需要你用add加入index后才能commit.
$git add file1 file2
然后将index的修改commit到本地.
$git commit file1 file2 -m "go! commit file1, file2"
以上两步(add, commit)也可以被合并成一步
$git commit -a file1 file2 -m "go! commit file1, file2"
如果需要更改上一次commit的信息
$git commit --amend -m "this is the right commit!"

这个时候文件只是在本地commit, 如果希望更新到远端的repositiory中, 还需要push(和更新源到本地的pull命令对应). 默认git push的话是push到origin的master分支
$git push
你也可以指定remote repo以及branch
$git push repo5 branch12
如果当前工作目录下checkout了多个branch, 但是你一般只会push正在tracking的这个branch,可以在config文件(比如.git/config)里设置
[push]
    default = tracking
或者使用命令
$git config push.default tracking

提取给定版本 checkout
checkout最新commit里的foo
$git checkout foo
如果需要提前两个版本的foo,可以
$git checkout HEAD~2 foo
从最新的stash(stash@{0})里checkout foo这个文件
$git checkout stash@{0} foo

撤销更改 revert, checkout, reset
比如你刚刚修改了一个文件foo, 但现在想撤销这个更改. 这需要根据foo的状态来选择不同的方法:
  • Changed but not updated: 如果一个文件foo被删除了, 或者被修改了但完全还在本地workspace中,还没有使用git add把foo加入index当中, 那么我们只需要重新checkout 这个文件
    $git checkout foo
    如果你不幸有一个branch也叫foo
    $git checkout -- foo
    如果你需要恢复当前目录所有文件
    $git checkout . 
    有时候需要把当前workspace中所有的修改都撤销,可以简单的使用:
    $git stash
  • Changes to be committed: 这时候修改已经加入index当中,但是还没有commit 提交到本地repo,我们可以使用reset使的当前workspace回到上一个commit的时候, 然后使用checkout恢复修改.
    $git reset HEAD foo
    $git checkout foo
    撤销所有index当中的修改:
    $git reset HEAD
  • 如果已经使用git commit把修改提交到了本地repo当中, 我们可以把本地repo rollback到上一次commit前的状态:
    $git reset --hard HEAD~1
    --hard选项会overwrite的所有的改动.

    如果我们只需要undo某一次的commit,可以使用git revert:
    $git revert b38155cbf671d55ceb027687c39508de8cef2463
    这样实际上是提交了另一个commit来抵消指定的commit.

查看日志 log
当前branch的commit日志
$git log
当前branch的commit日志,显示内容
$git log -p
当前branch的commit日志,但只显示上3次提交的内容
$git log -3
当前branch的commit日志,但只显示被修改的文件名
$git log --name-only

处理冲突 conflict
参考手册http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
以及 http://www.kernel.org/pub/software/scm/git/docs/git-push.html

pull的时候如果有本地修改会导致无法成功. 如果希望能把远端的commit merge到本地
$git checkout -m foo
Auto-merging foo
有可能会失败,这时候就需要你手动来编辑这个文件来merge了

push的时候, 当前commit到远端repo的时候,有时候会出现如下问题:
$git push
To git@example.come:example.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@example.com:example.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.
这是由于你的工作目录没有update到最新的版本.换言之有人在你上一次pull之后又push了新的commit进去.所以如果你的push生效, 可能会导致别人push的commit失效. 解决方法有两种:
$git pull
$git push
这种方法先把当前工作目录更新到最新 -- 这一步可能会产生冲突. 解决冲突后把更新提交. 这种方法会产生两个commit信息. 一次是说你自己的更新,另一次是将你的分支和repo上分支的merge.
如果不希望产生两次commit信息, 可以用第二种方法:
$git pull --rebase
$git push
这种方法直接将你的commit重新rebase到最新的版本上, 然后再进行提交.

分支 branch
一个repo可以有不同的分支,branch命令查看本地已有的分支, *表示当前使用的branch
$git branch
* master
  testbranch
可以用branch -r 查看remote所有的分支
$git branch -r
也可以用branch -a 同时查看local和remote所有的分支
$git branch -a
以当前branch的HEAD为起始点,新建新的branch叫newbranch
$git branch newbranch
也可以指定起始点(比如testbranch), 创建一个新的分支叫newbranch
$git branch newbranch testbranch

将当前分支从master切换到testbranch
$git checkout testbranch
$git branch
  master
* testbranch

删除一个local的branch
$git branch -d branch_to_delete
删除一个remote的branch
$git branch push origin --delete branch_to_delete
远端 remote
查看当前branch有哪些remote
$git remote
origin
查看当前branch有哪些remote,显示具体一些的信息
$git remote -v
origin git@example.com:bar.git (fetch)
origin git@example.com:bar.git (push)

查看origin这个remote的具体信息
$git remote show origin
一个repo可以有多个remote.比如给分支branch_foo添加一个新的remote:
$git remote add branch_foo git@host-for-new-remote:repo-name.git
将新添加的remote添加为tracking的branch
$git branch --set-upstream branch_foo   remote_bar/branch_foo

查看历史版本
查看某个版本(some-sha1)的某个文件
$git show some-sha1-number:some-file
查看某个版本(some-sha1)的和最新版本(HEAD)之间的所有区别
$git diff some-sha1 HEAD
查看某个版本(some-sha1)的和最新版本(HEAD)之间的某个文件的区别
$git diff some-sha1 HEAD --somefile

比较当前branch和另外一个branch比如叫foo的区别
$git diff foo
比较branch foo和另外一个branch bar的区别
$git diff foo bar
查看远端repo里的文件
查看当前HEAD中所有加入git管理的个文件
$ git ls-tree -r  HEAD

其他相关工具
tig - text-mode interface for git 设置git ignore的方法: http://help.github.com/ignore-files/

Saturday, July 17, 2010

赶个时髦,学习一下Object-C

(未完)
由于iPhone等Mac系产品无比红火的存在,Object-C也变得重要起来。Object-C是Apple的御用语言(类似C#之于Microsoft)。如果要开发个iPhone App啥的,就需要用到Object-C。如果要在MacOS里写点基于Cocoa的应用程序,也需要用到Object-C(其实Cocoa有python等其他语言的绑定,不过我试了一下不太喜欢)。

话说当年水果教教主Steve Jobs被董事会一脚踢出了自己创立的Apple,就搞了一个Startup叫做NeXT。Object-C就是NeXT从别人手里买下的。Steve Jobs在NeXT待了十年,期间潜心研发硬件软件,修为大为精进。而Apple这段时间却止步不前,终于在1997年被Steve Jobs夺舍而复辟回到了Apple。Steve Jobs顺道也把在NeXT修炼的OpenStep操作系统(打包了Object-C,Cocoa和Xcode等)带回了Apple,也就是后来广为人知的MacOS X。在使用Object-C的时候会发现大量NS开头的类(NeXTstep的意思),就是在纪念这段历史。

Object-C从名字上来看顾名思义就是包括了面向对象的C。道友可能会问,C++不就是用面向对象版的加强的C么?对,但其实现在我们看到的C++是那轮改造中涌现出来的最流行的那个。Object-C和C++都说自己继承了C语言,是C的超集--当你用不到面向对象的时候确实是这样。但是用上面向对象以后,两者的语法就存在着不小的区别。Object-C的面象对象部分其实处处都流露出从更加上古时期就流传下来的Smalltalk的影子。为了以示区别,Object-C中对于C扩充的关键字多以@开头,比如@interface,@end等。

下面开始步入正题:
第一个Object-C程序:Hello World

像学习其他所有语言一样,我们也不能免俗的从Hello World开始。下面是Object-C版本的Hello World
#import <stdio.h>

int main( int argc, const char *argv[] ) {
    printf( "hello world\n" );
    return 0;
}
不难发现,Object-C的Hello World和C版本的基本一样,唯一区别在于把#include换成了#import。没错,谁让Object-C就是C的扩充呢。

面向对象:类的创建

在Object-C当中, 首先用@interface定义一个类的成员变量和成员函数,然后在@implement中实现成员函数
Object-CC++
//Foo.h
@interface Foo : NSObject 
{ 
@private:
    double x;
@protected:
    double y;
@public:
    double z;
} 
-(int) f:(int)x; 
-(float) g:(int)x :(int)y; 
@end
//Foo.h
class Foo 
{ 
private:
    double x;
protected:
    double y;
public:
    double z;
    int f(int x); 
    float g(int x, int y); 
};
//Foo.m
#import "Foo.h"
@implementation Foo 
-(int) f:(int)x {...} 
-(float) g:(int)x :(int)y {...} 
@end 
//Foo.cpp
#include "Foo.h"
int Foo::f(int x) {...} 
float Foo::g(int x, int y) {...}

调用类方法

Object-CC++
[myObj method]
[myObj method:para1:para2]
output=[myObj method:para1:para2]
[obj1 func1:[obj2 func2]]
myObj.method()
myObj.method(para1,para2)
output=myObj.method(para1,para2)
obj1.func1(obj2.func2())
在Object-C当中,类方法的调用并不是传统的C/C++方式。而是采取了贴近Smalltalk的设计--消息。

Instance Method vs Class Method
在Object-C中,类的方法分为Instance 和Class两种,定义的时候分别使用"-"以及"+". Class method在大多数其他语言比如C++以及Java中又叫静态方法(static method).
@interface MyClass : NSObject

+ (void)aClassMethod;
- (void)anInstanceMethod;

@end
调用的时候
[MyClass aClassMethod];

MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];

Duck Typing

同受Smalltalk影响,Object-C和Python一样可以归入Duck Typing:一个类的实例可以调用该类中定义都方法,也可以调用该类中并没有定义的方法。在C++中如果一个类foo没有定义方法bar,那么foo的实例是无论如何也不能调用bar的--编译就无法通过。但是在Object-C(以及Python)中却没有问题--至少在编译期没有问题,但在运行期会有异常.

参考

从C/C++语言到Objective-C语言
Learning Object-C

Thursday, July 08, 2010

[Linux]readline

使用gnuplot的时候, 使用backspace 或者del这样的键总是显示~这样的字符
rlwrap -a -c gnuplot

这有一篇Consistent BackSpace and Delete Configuration
没有来得及仔细看

Tuesday, July 06, 2010

Virtualbox


Guest OS Addition
启动虚拟OS以后, 在device的menu里找到安装Guest OS Addition
安装这个的好处是鼠标可以自由移动, Guest OS的分辨率也会调整的比较好

共享文件夹
Host OS: Mac OS X
Guest OS: Ubuntu 9.04
为了在Guest OS中访问Host的文件系统,我们需要把Host的目录mount上

mount -t vboxsf [-o OPTIONS] sharename mountpoint
e.g. mount -t vboxsf -o uid=500,gid=500 /path/in/host /mount/point/in/guest

Guest OS: Windows XP
在Guest的Windows系统中访问MacOS上的目录,是通过映射网络硬盘实现的
在windows的命令行中输入
net use x: \\vboxsvr\sharename
这里x是你在Windows系统中分配的网络硬盘盘符,而sharename则是你在虚拟机中设置的共享文件夹(不一定是路径)

[Linux]动态链接库相关命令

Linux下动态链接库的管理
ldconfig 管理系统中的动态链接库文件

ldconfig这个命令会在“特定的路径”下搜寻可以共享的动态链接库文件(在Linux底下格式为lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和cache文件.这里"特定的路径"指/lib和/usr/lib这些默认路径以及动态库配置文件/etc/ld.so.conf内所列的目录以及文件.

如果刚刚安装了一个lib之后,相关文件仍然说找不到,可能是动态链接文件的cache没有更新.可以ldconfig把ld.so的cache更新一下:
ldconfig
只处理foo文件夹下的动态链接文件(前面描述的特定路径下就不处理了)
ldconfig -n foo
显示当前cache的动态链接文件
ldconfig -p

ldd
作用: 查看可执行文件需要的动态链接库
例子:
>ldd /bin/ls
 linux-vdso.so.1 =>  (0x00007fff549ff000)
 librt.so.1 => /lib/librt.so.1 (0x00007fd82409c000)
 libselinux.so.1 => /lib/libselinux.so.1 (0x00007fd823e7e000)
 libacl.so.1 => /lib/libacl.so.1 (0x00007fd823c75000)
 libc.so.6 => /lib/libc.so.6 (0x00007fd8238f2000)
 libpthread.so.0 => /lib/libpthread.so.0 (0x00007fd8236d5000)
 /lib64/ld-linux-x86-64.so.2 (0x00007fd8242c8000)
 libdl.so.2 => /lib/libdl.so.2 (0x00007fd8234d0000)
 libattr.so.1 => /lib/libattr.so.1 (0x00007fd8232cb000)


是否应该使用环境变量LD_LIBRARY_PATH?
答案是no.尽量不要设置这个变量.理由参见http://linuxmafia.com/faq/Admin/ld-lib-path.html


Mac下的动态链接
ldd对应otool

Ref
http://wiki.linuxquestions.org/wiki/Library
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

[Latex]几招压缩Latex paper的页数

写paper的时候要压缩页数常常让人很痛苦.其实默认的Latex的paper尚有很大的空间,让你不动太多的内容改动就大大的压缩论文页数.下面我贡献常用的几招
调整Section title的font和spacing
\usepackage[medium,compact]{titlesec}
默认的section title啥的其实spacing相当大.所以别看这招简单, 但其实相当狠, 能省下来很大的空间.

对于Bibliography参考文献用小号字体
可以用 \small, 再小点用 \footnotesize, \scriptsize 也有人用. 不过\tiny就太小了,reviewer会有意见的.
\footnotesize
\bibliography{ref}
\bibliographystyle{abbrvnat}

标准的itemize环境里的indent吃掉了很多空间,可以用list环境来自定义左右间距等参数
\begin{list}{\labelitemi}{\leftmargin=1em}
  \setlength{\topmargin}{0pt}
  \setlength{\itemsep}{0em}
  \setlength{\parskip}{0pt}
  \setlength{\parsep}{0pt}
\item blablabla
\item blablabla
\end{list}
在这里我们用\labelitemi (实心圆点)作为每个item开头的bullet.还可以用预定义好的\labelitemii (一个-)或者\quad (空白)甚至 $\star$这样的.
或者可以这样全局的来设置:
\usepackage{enumitem}
\setlist{itemsep=0pt,parsep=0pt}

调整Equation和前面文字的空间
公式和文字之间有时候会留下很大的间距,可以通过\vspace来压缩这个间距
Therefore,
\vspace*{-0.5\baselineskip}
\begin{eqnarray}
     A = B
\end{eqnarray}

Monday, June 28, 2010

[Linux]以安全模式启动firefox或是thunderbird

不小心装了有问题的add-on然后firefox或者thunderbird就启动不起来了?
/path/to/firefox/firefox -safe-mode
/path/to/thunderbird/thunderbird -safe-mode

卸载掉有问题的add-on之后就好了

Saturday, April 17, 2010

[Python]py2app:将python程序转换为Mac OS Application的工具

先安装py2app
安装完毕后会有一个叫py2applet的程序出现
接下来进入我们python程序的目录,比如我们的程序叫HelloWorld.py
第一步: 生成HelloWorld的setup.py
$ py2applet --make-setup HelloWorld.py
第二步: 生成HelloWorld.app的结构
$ python setup.py py2app -A

[Linux]cheeting sheet of sh, csh, bash

sh, csh, bash 比较

Statement sh tcsh bash
if-then-else
if [ expression ] 
then
    ...
else
    ...
fi
if (expression) then
    ...
else
    ...
endif
注:then必须和if同一行
if [ expression ]
then
    ...
else 
    ...
fi 
for-loop
for var in (list)
do
    ....
done
foreach var (list)
    ...
end
for var in [list]
do
    ...
done 
Loop in Bash: http://www.cyberciti.biz/faq/bash-for-loop/

Sh: http://www.freeos.com/guides/lsst/
Bash: http://tldp.org/LDP/abs/html/

Monday, March 29, 2010

[Linux/Mac]package/library管理工具

Ubuntu


很好的一个reference: Ubuntu Skills

安装软件
  • 从源安装是最方便最快捷的方式. 源的设置在/etc/apt/sources.list当中.
    如果知道需要安装的包的名称, 比如叫foo. 那么安装foo只需要
    apt-get install foo
    如果不知道确切名字,只知道大概是关于foo这个东西的, 可以通过下面的命令来搜索所有关于foo的包
    apt-cache search foo
    还有时候连包都不知道, 但是只知道需要某个文件比如叫foo.c,但不清楚应该装哪个包, 这时候可以先安装apt-file
    apt-get install apt-file
    然后用apt-file来帮你找可能是哪个包有这个文件
    apt-file search foo.c
  • 也可以下载deb文件来安装
    dpkg -i foo.deb


自动更新所有过时的package
apt-get update
卸载package foo
apt-get remove foo
彻底卸载package foo (连同配置文件一起删除)
apt-get remove --purge foo
自动卸载不需要的包
apt-get autoremove
查看某个包foo的详细信息
apt-cache show foo
查看repository中package foo的版本
apt-cache policy foo
添加某个源的key
apt-key add bar.asc

安装完之后, 通常用dpkg来管理包
查看package foo所安装的文件以及路径
dpkg -L foo
显示包的信息
dpkg -s packagename
显示包括指定文件的包
dpkg -S filename
显示指定包的状态
dpkg --get-selections packagename
配置某个包
dpkg --configure packagename
配置所有的包
dpkg --configure -a


MacOS中的home brew

https://github.com/mxcl/homebrew/wiki/The-brew-command
非常好用的MacOS下的包管理软件.强烈推荐.
一个brew的cheatsheet: http://cheat.errtheblog.com/s/brew/ 一个安装包时候常遇到的问题
$ sudo brew install ruby
Cowardly refusing to `sudo brew install'
这是by design. 我的解决方法是吧brew的onwer设成root
brew install foo
brew cleanup foo

如何为brew制作Formula:Formula Cookbook

MacOS中的port

关于port的使用MacPorts Guide
安装包foo
port install foo
删除包foo
port uninstall foo
查看包foo的相关信息
port info foo
查看所有过时的包
port outdated
更新所有过时的包
port upgrade outdated
查看已经安装的包
port installed
清除所有已安装包的临时文件
port clean --all installed
彻底删除旧的包
port -f uninstall inactive
删除inactive的包
port -u uninstall
port uninstall inactive
清理foo包的中间文件(比如损坏了)
port clean foo
安装foo这个包之前先将其deactivate
port deactivate foo
port activate foo
查看foo这个包都在本机安装了哪些文件
port contents foo
查看foo这个包都依赖哪些其他包
port deps foo
查看哪些包依赖foo
port dependents foo

Hadoop Related

参考文档

收集的一些关于Hadoop的链接
Official Docs
Hadoop Quick Start (Official)
Hadoop MapReduce Tutorial using Java
Hadoop MapReduce Tutorial using Streaming
Hadoop Command Line
Jobconf parameters
Hadoop API Doc (Java)

Cluster Setup
Job Configuration的选项和默认值(有点老, 0.15的, 不过大部分没变)
Other Tutorials
Cloud 9: 关于hadoop的介绍很好很具体.有一些关于具体的programming的指导.
Hadoop Really Quick Start
Cloud computing with Linux and Apache Hadoop
The Hadoop Distributed File System

Hadoop自带工具

大部分初学者可能的问题, 先看Hadoop FAQ

DistCp

bash$ hadoop distcp hdfs://nn1:8020/foo/src1 \ 
            hdfs://nn1:8020/foo/src2 \ 
            hdfs://nn2:8020/bar/dest 

bash$ hadoop distcp -f hdfs://nn1:8020/srclist \ 
            hdfs://nn2:8020/bar/foo 

用RandomTextWriter生成随机文本
hadoop jar ${HADOOP_HOME}/hadoop-*-examples.jar randomtextwriter\
  -D test.randomtextwrite.total_bytes=52428800 \
  -D test.randomtextwrite.bytes_per_map=5242880 \
  /data/rand-text
参数test.randomtextwrite.total_bytes指定总共有多少字节要写;参数test.randomtextwrite.bytes_per_map指定每个map写多少字节.

Sort
hadoop jar ${HADOOP_HOME}/hadoop-*-examples.jar sort \
  -outKey org.apache.hadoop.io.Text \
  -outValue org.apache.hadoop.io.Text \
   /data/rand-text /data/sorted-text

Grep
hadoop jar ${HADOOP_HOME_DIR}/hadoop-*-examples.jar grep \
  /data/rand-text /data/greped-text dfs[a-z.]+' 

参数tips

reducer需要内存超过默认的1024MB的话,可以通过参数调整:
-D mapred.job.reduce.memory.mb=2048

使用Java作Hadoop MapReduce的时候,如果用到其他第三方的jar文件,用-libjars 选项来include

可以用-file选项指定需要使用的脚本
-file=myscript.sh

使用Streaming的时候,每个map task最多只能处理一个输入文件. 因此如果输入包括100个文件,则至少需要100个map.如果设定的mapred.map.tasks数目小于100,Hadoop会自动调整为100.

压缩格式的输入
当输入是gz或者是bz2文件时,不需要做特殊的处理.
-D stream.recordreader.compression=gzip

压缩格式的输出
当希望输出是压缩格式(比如.gz文件)时, 可以加上下面的选项
-D mapred.output.compress=true \
-D mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCode

指定map以及reduce的数目
指定map数目
-D mapred.map.tasks=your_map_number
指定reduce数目
-D mapred.map.tasks=your_reduce_number
特别的,使用map only 的MapReduce job时,
-D mapred.reduce.tasks=0

使用identityMapper作为mapper或者reducer
-mapper org.apache.hadoop.mapred.lib.IdentityMapper
-reducer org.apache.hadoop.mapred.lib.IdentityReducer

Key,Value的划分
对于streaming job,需要将map的输出划分成key和value.默认的划分是第一个"\t"之前的是key,之后的是value.但是我们可以自定义分隔符,比如要用=作为分割:
-D stream.map.output.field.separator==
也可以指定第几个分隔符之前的作为key:
-D stream.num.map.output.key.fields=4

Primary, Secondary Key
Hadoop Mapreduce 默认根据key来分配reducer使得所有key一样的record都被同一个reducer处理.有时候我们希望每个record是这样的格式 (k1,k2,v), 然后所有k1(也就是primary key)一样的record被同一个reducer处理, 而这个reducer看见的所有k1的record按照k2来排序.这样的要求可以通过类似下面的代码来实现: 比如这里将map输出里每行的前2个field作为k1也就是partition参考, 而第3第4个field作为k2来排序
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
-D stream.num.map.output.key.fields=4 \
-D num.key.fields.for.partition=2


输出路径可以在命令行中用${mapred.output.dir}指定或者在程序中用JobConf.setOutputPath来指定

Friday, February 19, 2010

[Linux]Makefile速查

基本语法:
target: prerequisites
    command
target:规则生成的目标. 可以是最终的目标文件,也可以是中间文件,还可以是“伪目标”(比如all,clean)
prerequisites:生成规则目标所需要的文件名列表
command:生成规则目标所要执行的动作,可以是一行也可以多行.但每行必须以tab开头

一个Makefile就是由一个或多个规则构成.默认的情况下,make执行的是Makefile中的第一个规则.比如下面例子:
# 定义变量可以方便修改
objects = main.o utils.o
#默认最终生成目标:edit
edit : $(objects)
    cc -o edit $(objects)
#指给定.o目标所需要的.h文件,make自动使用.o文件同名的.c文件,并且使用cc编译
main.o : defs.h
utils.o : defs.h
#告诉make clean是一个伪目标而不是真实文件
.PHONY : clean
clean :
    rm edit $(objects)

内部宏:
$?:比目标的修改时间更晚的那些依赖模块表。
$@ :当前目标的全路径名。可用于用户定义的目标名的相关行中。
$<:比给定的目标文件时间标记更新的依赖文件名。
$* :去掉后缀的当前目标名。例如,若当前目标是pro.o,则$*表示pro。

通配符
HEADERS=$(wildcard ./*.h)

参考:
[1] GNU Make中文手册

Thursday, February 18, 2010

[数学]抽扑克

2n张牌,n张红n张黑.随机从这副牌里连续抽牌(抽出来后就不扔回去了),平均能够看见多少次连续两张红牌?如连续三张红牌,视为看见两次.平均能看见多少次前一张红牌后一张黑牌?

Sol: 先定义随机变量
I_{i}=\begin{cases} 1 & \textrm{ith,(i+1)th are both read}\\
0 & \textrm{otherwise}
\end{cases}
这样能看见的连续红牌次数X = I_1+I_2+...+I_(2n-1). 虽然I_i和I_j之间并不独立(比如你前n张都抽的是红牌,那么后n张只能是黑牌了),但是如果是对X求期望,就可以把各个I_i单独拎出来求期望,再对期望求和:
E[X] = E[I_1]+\cdots+E[I_{2n-1}]=(2n-1)\frac{n}{2n}\frac{n-1}{2n-1}=\frac{n-1}{2}
同理可以得到看见先红后黑的平均次数是 n/2

Saturday, February 06, 2010

[数学]关于扔硬币得到的序列

现在有一枚硬币, 每次以概率p得到正面(下面以H代表),概率q=1-p得到反面(以T代表).反复投掷这枚硬币并记录出现的结果序列, 比如 T H H T T T H H T H...这样的一个序列. 针对这个序列我们可以说,在时间4我们完成了一个pattern THHT, 在时间6我们完成pattern TTT, 时间9又重复出现了pattern THHT.

下面是一些直观上容易理解的以及费解的:)结论: 

  1. 一个长度为k的给定pattern,在t时刻出现的概率为 p^i q^(k-i).这里i是pattern中T出现的次数. 这个很好理解.比如TTT在任意时刻出现的概率是p^3,  THHT是p^2 q^2, HTHT也是p^2 q^2
  2. 同一个pattern, 两次出现的时间间隔的期望是 1/[p^i q^(k-i)]. 这个结果也很直观. 可以根据Delayed Renewal Process得到. 所以THHT出现间隔是1/(p^2 q^2),HTHT出现间隔也是1/(p^2 q^2)
  3. 一个pattern, 从第一次扔硬币开始到第一次出现的时间期望

    E[time until HTHT] =  E[time until HT] + E[time between HTHT] = E[time between HT] + E[time between HTHT] = 1/(pq) + 1/(p^2 q^2)

    这里的一个trick是把pattern HT和HTHT之间的时间间隔等同于出现pattern HTHT 的间隔. 仔细想一下的话, 出现一次HTHT后这个pattern对下一次出现HTHT的贡献(或者影响)就是它的尾巴HT了. 同理我们还有

    E[time until THHT] =  E[time until T] + E[time between THHT] = E[time between T] + E[time between THHT] = 1/p + 1/(p^2 q^2)

    所以从第一次投硬币开始观察的话,  HTHT和THHT第一次出现的平均时间是不同的.
    同样我们也可以得到连续k个T出现的平均时间, 注意每一次连续出现i个T都对i+1个T有贡献

    E[time until k consecutive T] = 1/p + 1/p^2 + ... + 1/p^k

这个问题还有一个利用Martingale的方法来算,而且是Bob Li提出来的(A martingale approach to the study of occurrence of sequence
patterns in repeated experiments, Annals of Probability, 1980).比如我们要求E[time until HTHT].设在第i轮,一个赌徒下注1块钱.如果第i轮结果是H,赌徒就赢得1/p块钱,接下来第i+1轮结果是T,赌徒就赢得1/(pq)块钱,以此类推.不过如果一旦没有压准,所有钱就输了.请注意这是一个公平赌博.如果每一轮都有一个赌徒来下注.设Xn为第n轮下来赌场的收入:
Xn=(n-4) - [1/(p^2 q^2) -1] + 1 - [1/(pq) -1 ] + 1

因为Xn是Martingale,所以 0 = E[Xn] = (E[n]-4) - [1/(p^2 q^2) -1] + 1 - [1/(pq) -1 ] + 1
也就得出E[n] = 1/(pq) + 1/(p^2 q^2)

Monday, February 01, 2010

[数学]比较k个随机数加权后的大小

如果有k个随机变量x_1..x_k独立同分布于U[0,1],每个随机变量对应一个非负权重a_1...a_k.
那么加权后第一个随机变量比其他随机变量加权后都大的概率(i.e., a_1x_1>= a_ix_i for all i):

Sol:
如果给定x_1=x, a_1x_1比a_ix_i大的概率为min(a_1x_1/a_k,1)

\int_{0}^1\min(\frac{a_1x}{a_2},1)\cdots \min(\frac{a_1x}{a_k},1) d x

Tuesday, January 19, 2010

[数学]关于Coupon Collector的问题

原题在这里.简单的说,市面上有一种coupon有n个样式.每一个你新收集的coupon以1/n的概率为其中任意一种.如果说你需要收集T个coupon你才能把所有的样式都拿到,那么T的均值是多少呢?

假设我们手里已经有了i-1种不同的coupon.那么在收集了i-1种不同coupon后,出现一个新式的coupon所需要的尝试次数服从参数为pi的几何分布.pi=(n-i+1)/n 也就是出现第i种新coupon的概率.
E[T]=1/p_1+1/p_2+\cdots+1/p_n =  \frac{n}{n}+\frac{n}{n-1}+\cdots+\frac{n}{n} = n H_n\approx n \ln n


该问题的一个变种是:求当我们收集齐了所有n种coupon,其中某个样式(比如印着机器猫的)coupon只拿到了一张的概率.

该珍贵的coupon,可以是第1种收集到的,也可以是第j种收集到的.j服从1,...,n,的均匀分布.如果它是第j种收集到的coupon,则后面不出现该coupon的概率是 1/(n-j+1). 所以全概率是:
\sum_{j=1}^n \frac{1}{n}\frac{1}{n-j+1}= \frac{H_n}{n}\approx \frac{\ln n}{n}

Sunday, January 17, 2010

[Emacs]我总结的Emacs Cheating Sheet

这有一个不错的pdf版本cheat Sheet:Emacs Cheat Sheet

C代表Ctrl键, M代表Meta键, ←和→是右箭头和左箭头
基本操作
这里总结的是基本操作,大多数mode下都可以用
在文本中移动
C-f, C-b 向前(C-f)或是向后(C-b)移动到下一个字符.
M-f, M-b 向前(M-f)或是向后(M-b)移动到下一个单词.
C-M-f, C-M-b 在一对匹配的括号间,向前(C-M-f)或是向后(C-M-b)跳转.
C-a,C-e 移到当前行首(C-a)或者行尾(C-e).
M-a, M-e 向前(M-a)或是向后(M-e)移动到下一个句子.
C-x C-space 跳转到上一个mark的地方
C-v,M-v 向前(C-v)或是向后(M-v)翻页
M-<, M-> 移动到buffer首/尾
M-m 移动到第一个非空格字符。(back-to-indentation)
M-r 加参数,移动到窗口里的某一行。不加参数缺省移动到窗口中间。
M-x goto-char 到文件的第 N 字节。
M-x goto-line 到文件第 N 行。
C-x C-n 设定 goal-column.
C-u C-x C-n 取消 goal-column.
M-g g 移动到指定行

编辑文本
C-o 当前位置插入一行
M-Delback,M-d 以word为单位的前删/后删
C-d 删除后面一个字符且不放入kill-ring
C-M-k 向前删除直到匹配括号
Esc-C-Del,Esc-C-Backspace: 先后删除到匹配括号
M-z : 删除到下一个出现的位置

大小写转换
从光标位置开始,处理单词后半部分
capitalize-word (M-c) -- 首字母改为大写
upcase-word (M-u) -- 全部改为大写
downcase-word (M-l) -- 全部改为小写
从光标位置开始,处理单词前半部分
negtive-argument; capitalize-word (M-- M-c)
negtive-argument; upcase-word (M-- M-u)
negtive-argument; downcase-word (M-- M-l)
改变选定区域的大小写 downcase-region (C-x C-l) -- 选定区域全部改为小写
upcase-region (C-x C-u) -- 选定区域全部改为大写


设定Marker
C-空格,C-@ 设定一个mark
C-x h 整个缓冲区全部mark

对齐 (http://www.emacswiki.org/emacs/AlignCommands#toc2)
M-x align 对齐当前选择
M-x align-current 对齐当前section
M-q fill-paragraph 对一个段落排版

获取帮助
C-h c 简要描述给定键绑定
C-h k 详细描述给定键帮定
C-h f 描述给定函数
C-h v 描述给定变量
C-h m 描述当前mode
键/键组合 C-h 以当前键/键组合开头的绑定
M-x `finder-commentary' RET foo RET.

查找
C-s 向前方查找
C-r 向后方查找

注释
M-; 注释一个区域或者去掉区域的注释 (需要开启transient-mark-mode以后)

操作矩形
首先Set Marker然后移动光标围成一个矩形区域
C-x r k 删除矩形区域
C-x r t 矩形区域中插入文本

切换不同窗口
C-x 0 删除当前窗口(注意是零不是o)
C-x o 把光标在屏幕上的窗口间进行切换。记忆方法:其它(other)窗口。
C-x 1 把当前光标所在的窗口放到最大,隐藏其它所有的窗口。记忆方法:只剩一(1)个。
C-x 2 水平切分屏幕
C-x 3 竖直切分
C-x w r 1 存储当前窗口layout到寄存器1(可以为其他数字)
C-x j r 1 读取寄存器1(可以为其他数字)中的窗口layout

切换不同buffer
C-x b 缓冲区名称. emacs会提供一个缺省的缓冲区,一般是上一个用到的.如果不行,手动输入缓冲区名称,支持和自动补全.
C-x C-b 列出缓冲区菜单. 但这个命令不会将光标移动到缓冲区菜单的窗口中,需要C-x o命令切换过去.
C-x →,C-x ←. 循环切换到前一个(后一个)缓冲区
C-x k 杀死一个缓冲区(默认是当前缓冲区)
C-x C-s 保存当前缓冲区

切换不同frame
C-x 5 0 切换frame

在Emacs中使用Shell buffer
M-x ansi-term 带有色彩支持的term
M-x shell 系统默认shell
M-x eshell emacs自带shell

参数
M-<数字> : 执行 <数字>这么多次
C-u <数字> : 同上



常用Mode下的操作
AucTex LaTeX mode
C-c C-b 编译buffer / 预览编译结果
C-c C-r 编译选定的region
C-c C-c 运行定义好的命令比如 latex, view, bibtex
C-c C-v 查看当前的output file
C-c C-e 添加指定的环境
C-u C-c C-e 替换当前的环境
C-c ] 添加\end{...} 来匹配当前环境
C-c ; 注释选定区域,再操作一次就是去除选定区域的注释

CC mode
子模式:
auto-state 当你输入时自动缩进,自动换行
hungry-state 当你Backspace时,自动删除尽可能多的空白和空行
C-c C-t 同时转换(开/关)auto-state和hungry-state子模式
C-c C-a 转换 auto-state 子模式
C-c C-d 转换 hungry-state 子模式

M-/ 自动补齐(缓冲区中能找得到的串)
M-; 行尾加入注释
C-c C-e 扩展宏
C-c C-c 注释掉整个区域
C-c C-\ 将区域中的每一行结尾都加入一个'\'字符

cc-mode下的缩进
C-c . 设置缩进风格(按TAB键可列出可用的风格,缺省的为gnu,其 缩进为2个字符;linux为8个;k&r为5个…)
C-c C-q 缩进当前函数
C-M-q 缩进当前表达式
tab 缩进当前行
C-x h C-M-\ 缩进当前buffer
C-M-u C-M-q 缩进当前block

Lisp mode (http://www.delorie.com/gnu/docs/emacs/emacs_329.html)
C-: 执行一行lisp
C-x C-e 执行光标前的lisp

VC (version control) mode(http://lifegoo.pluskid.org/wiki/EmacsVC.html ,http://lifegoo.pluskid.org/wiki/EmacsVC.html , http://www.credmp.org/?p=65)
C-x v i 添加当前buffer的文件到version control当中
C-x v v 下一个合理的version control 动作(通常在一个状态下只有一个合理动作)
C-x v m 更新当前文件
C-x v + 更新当前文件集合
C-x v d 显示一个目录下所有注册到版本控制下的文件
C-x v l 查看log
C-x v = 和repository上代码作比较
C-x v ~ 查看以前版本

org mode (官方手册 , 中文教程)
Org mode是Emacs上一个用于组织信息,管理信息,撰写大纲的利器.可以帮助你非常快速的组织思路,查找信息.
C-c C-t Rotate the TODO state of the current item among
C-Shit-Enter 新建一个TODO 项目
Shit+Tab 切换view
链接:
[[链接地址][链接名称]]比如 [[http://www.gnu.org/software/emacs/][GNU Emacs]]
或者 [[链接地址]]如果你不需要名称


Cscope Mode
C-c s a 设定初始化的目录,一般是你代码的根目录
C-c s I 对目录中的相关文件建立列表并进行索引
C-c s s 序找符号
C-c s g 寻找全局的定义
C-c s c 看看指定函数被哪些函数所调用
C-c s C 看看指定函数调用了哪些函数
C-c s e 寻找正则表达式
C-c s f 寻找文件
C-c s i 看看指定的文件被哪些文件include

Dired mode (http://jamesthornton.com/emacs/node/emacs_396.html#SEC396 , http://www.20seven.org/journal/2008/11/emacs-dired-directory-management.html)
Dired mode用于文件管理
C-x d/M-x dired 进入Dired模式
C copy
D delete
# 标记所有atusave文件
R rename
s sort

iBuffer mode (http://www.emacswiki.org/emacs/IbufferMode)
和Dired mode相仿,但是用于buffer管理
M-x ibuffer 进入ibuffer模式
m 选定当前位置buffer
u 去除选定当前位置buffer
t 改变buffer list里每个buffer的选定状态
D 删除当前选定的buffer(们)
g 刷新
% n 选定所有那些buffer名称符合给定正则表达式的
% m 选定所有那些mode名符合给定正则表达式的
% f 选定所有那些文件名符合给定正则表达式的

GDB
M-x compile RET 编译
M-x gdb RET 调试
gdb --annotate=3 a.out 或者 gdb -i=mi a.out
C-x ` (出错信息中)下一个错误,一个窗口显示错误信息,另一个显示源码的出错位置
C-c C-c 转到出错位置

启动gdb调试器后,光标在源码文件缓冲区中时:
C-x SPC 在当前行设置断点
C-x C-a C-s step
C-x C-a C-n next
C-x C-a C-t tbreak
C-x C-a C-r continue

其他一些七七八八的

设置AucTex中的viewer. AUCTeX以前是通过设置TeX-output-view-style和TeX-view-style来决定如何根据output文件的后缀来用不同的viewer打开output文件. 新的实现是通过设置TeX-view-program-list和TeX-view-program-selection两个变量来实现:
比如把pdf和dvi文件关联到Evince.
(setq TeX-view-program-list '(("Evince" "/usr/bin/evince --page-index=%(outpage) %o")) )
(setq TeX-view-program-selection '((output-pdf "Evince") (output-dvi "Evince")) )

--could be out of date---
改变AUCTeX默认pdf viewer:
"Customize group - Auctex - Tex Command" entry for the "^pdf" extension in
"Tex Output View Style" => "evince %o"

重要变量
major-mode: 当前mode

载入.emacs文件
M-x load-file RET ~/.emacs RET Reload .emacs without restarting

check the value of your load-path by asking for help on the variable: ‘C-h v load-path RET’

By default Emacs doesn’t include subdirectories of a directory which is added to load-path. But you can do it by issuing a command in startup file:

(normal-top-level-add-subdirs-to-load-path)

Recover Data
M-x recover-file <ret> foo.c <ret>
yes <ret>
C-x C-s

查看package路径
M-x locate-library

在eclipse当中绑定emacs键位设定
Window->Preferences->General->Keys Scheme中选emacs

强制使用某种mode 比如xxx-mode
M-x xxx-mode

刷新当前文件
M-x revert-buffer
刷新所有已经打开的文件
M-x revert-all-buffers

去除所有结尾的whitespace
M-x delete-trailing-whitespace

绑定key http://www.xemacs.org/Links/tutorials_2.html http://www.gnu.org/s/emacs/manual/html_node/elisp/Key-Binding-Commands.html
(global-set-key (kbd "C-x C-\\") 'next-line)

显示行号(类似vi中的 :set nu)
(global-linum-mode t)

如果希望emacs帮你自动wrap line,
M-x auto-fill-mode

判断当前系统
(if (eq system-type 'windows-nt) do-what-you-like)
如果是MacOSX, 把'windows-nt换成'darwin

C-\ 切换 "拼符"输入法