2011
09.15

Home Network Setup

家庭网络设置的需求

LAN

在家里,应该做到在任何地方都可以连上网络,而不是必须坐在电脑桌前;目前可以上网的移动设备比电脑还多。因此Wifi网络是必须的。

如果还在使用百兆的网络,拷贝一份20G的高清电影你需要30多分钟。而如果使用千兆网络,同样拷贝一份20G的电影,只需要3分钟多一些。当然硬盘可能不够快,以致实际上需要10多分钟才能完成。所以需要千兆网络交换机。

需要设备一接上,不需要配置就应该能够互连。IPv4的情况下,还是DHCP服务器自动分配IP比较方便的。

Internet

家庭网络内的设备都需要访问互联网,需要一个路由器做网关。

目前运营商为家庭用户提供的互联网接入方式还是以PPPoE为主。

运营商提供的域名解析服务器不靠谱,部分域名还被污染。用8.8.8.8或opendns这样的解析服务可能无法解析到最佳网络连接的主机。自建的解析服务器还可以解析内部网络的主机。

架一个HTTP代理服务器能够很大程度提高互联网页面的访问速度。

翻墙,这属于基础设置。需要做到网络层的翻墙,简单的HTTP代理不够。

Remote Access

需要从外部通过互联网访问家庭网络,例如从办公室查看家里的一篇文档。OpenSSH能够提供最基本的远程访问,管理家庭网络内的设备。

在外的时候,笔记本电脑或者移动设备还能够是家庭网络的一部分,这时候就需要虚拟的私有网络了。OpenVPN可以采用证书的认证方式,将作为缺省方案;还需要PPTP服务器来满足临时的需求,因为PPTP的客户端在很多系统上都是自带的,还有未越狱的iOS设备还无法使用OpenVPN,但可以使用PPTP。

运营商提供的是动态的IP地址,每次重新建立PPPoE连接的时候都会换一个IP。为了能够从互联网上访问家庭网络,需要动态的域名解析。

NAS

网络文件服务器,可以在内部网络共享电影、音乐、文件等,还有TimeMachine。同一个存储空间可以通过各种协议访问。

Mac设备间通过AFP最方便;Linux机器使用NFS比较方便;提供CIFS/Samba,让Windows客户端不需要另外安装任何软件就能够直接访问共享存储。

IPv6

访问只有IPv6服务的网站,可以显摆。6in4的tunnel服务还没有被GFWed,也可以用来翻墙,而且速度相当快(上海电信FTTH至he.net位于加州的机房可以有近10Mbps的吞吐量)

Security

需要对家庭网络做访问限制,特别是远程来的访问。

内部网络和外部的网络应该物理隔离,物理隔离是指内部网络和外部网络必须跑在不同的网卡、不同的交换机VLAN上。

还需要做网络包过滤。

eeebox-b202

2011
07.31

8 puzzle (python)

重排九宫

+---+---+---+      +---+---+---+
| 1 | 2 | 3 |      | 8 | 7 | 6 |
+---+---+---+      +---+---+---+
| 4 | 5 | 6 |  ==> | 5 | 4 | 3 |
+---+---+---+      +---+---+---+
| 7 | 8 |   |      | 2 | 1 |   |
+---+---+---+      +---+---+---+

$ 8puzzle.py -f2
# 30
Number of states enqueued = 14754

#!/usr/bin/env python

import sys
from optparse import OptionParser
import math
from struct import pack
import heapq

class Solver:
    def __init__(self, n):
        self.N = n
        self.L = n * n

        self.GOAL = range(1, self.L)
        self.GOAL.append(0)

        # slide rules
        self.SR = {}
        for i in range(self.L):
            s = []
            if i - self.N >= 0:
                s.append(i - self.N)
            if (i % self.N) - 1 >= 0:
                s.append(i - 1)
            if (i % self.N) + 1 < self.N:
                s.append(i + 1)
            if i + self.N < self.L:
                s.append(i + self.N)
            self.SR[i] = s

        # queue
        self.queue = []
        self.enqueued = {}

        # verbose
        #self.verbose = 104999
        self.verbose = 8963

        # h
        self.w = 1
        self.h = self.heuristics

    def is_solvable(self, tiles):
        x = 0
        for p in range(len(tiles)):
            a = tiles[p]
            if a < 2 :
                continue
            for b in tiles[p:]:
                if b == 0:
                    continue
                if a > b:
                    x = x + 1
        return (x & 1) == 0

    def neighbors(self, tiles):
        n = []
        a = tiles.index(0)
        for b in self.SR[a]:
            n.append(self.swap(list(tiles), a, b))
        return n

    def swap(self, tiles, a, b):
        tiles[a], tiles[b] = tiles[b], tiles[a]
        return tiles

    def display(self, tiles):
        for i in range(self.L):
            if tiles[i]:
                print '%(n)#2d' % {'n': tiles[i]},
            else:
                print '  ',
            if i % self.N == self.N - 1:
                print

    def enqueue(self, state):
        (tiles, parent, h, g) = state

        if self.verbose > 0 and len(self.enqueued) % self.verbose == self.verbose - 1:
            print " -->", len(self.enqueued), g

        f = h * self.w + g;
        heapq.heappush(self.queue, (f, state))

    def dequeue(self):
        if len(self.queue) <= 0:
            return None
        (f, state) = heapq.heappop(self.queue)
        return state

    def heuristics(self, tiles):
        return 0;

    def manhattan(self, tiles):
        h = 0
        for i in range(self.L):
            n = tiles[i]
            if n == 0:
                continue
            h += int(abs(n - 1 - i) / self.N) + (abs(n - 1 - i) % self.N)
        return h

    def hamming(self, tiles):
        h = 0
        for i in range(self.L):
            n = tiles[i]
            if n > 0 and n - 1 != i:
                h += 1
        return h

    def solve(self, initial):
        if not self.is_solvable(initial):
            return None

        state = (initial, None, self.h(initial), 0);
        if initial == self.GOAL:
            return state

        self.enqueue(state)

        while True:
            state = self.dequeue()
            if (not state):
                break

            (tiles, parent, h, g) = state
            neighbors = self.neighbors(tiles)
            for n_tiles in neighbors:
                if n_tiles == self.GOAL:
                    return (n_tiles, state, 0, g + 1)

                packed = pack(self.L*'B', *n_tiles)
                if (packed in self.enqueued):
                    continue;
                self.enqueued[packed] = True                        

                n_state = (n_tiles, state, self.h(n_tiles), g + 1)
                self.enqueue(n_state)

def main(options, args):
    initial = []
    if args:
        for n in args:
            initial.append(int(n))
    else:
        initial = [8,7,6,5,4,3,2,1,0]

    solver = Solver(int(math.sqrt(len(initial))))

    solver.verbose = int(options.verbose)
    solver.w = float(options.weight)
    if int(options.function) == 1:
        solver.h = solver.hamming
    elif int(options.function) == 2:
        solver.h = solver.manhattan

    state = solver.solve(initial)
    if not state:
        print "No solution possible"
        return 1

    solution = []
    while state:
        (tiles, parent, h, g) = state
        solution.insert(0, tiles)
        state = parent

    n = 0
    for tiles in solution:
        print "#", n
        solver.display(tiles)
        print
        n += 1

    print "Number of states enqueued =", len(solver.enqueued)
    return 0

if __name__ == '__main__':
    parser = OptionParser(usage="usage: %prog [options] [tile] [tile] [tiles ...]")
    parser.add_option("-v", "--verbose", metavar="<level>",
            default=8963)
    parser.add_option("-f", "--function", metavar="<fid>",
            help="heuristics function. 1 for hamming, 2 for manhattan [default: None as breadth first]",
            default=0)
    parser.add_option("-w", "--weight", metavar="<n>",
            help="weighting of the heuristics function [default: 1]",
            default=1)
    (options, args) = parser.parse_args()

    sys.exit(main(options, args))
+----+----+----+----+       +----+----+----+----+
| 15 | 14 | 13 | 12 |       |  1 |  2 |  3 |  4 |
+----+----+----+----+       +----+----+----+----+
| 11 | 10 |  9 |  8 |       |  5 |  6 |  7 |  8 |
+----+----+----+----+  ==>  +----+----+----+----+
|  7 |  6 |  5 |  4 |       |  9 | 10 | 11 | 12 |
+----+----+----+----+       +----+----+----+----+
|  3 |  1 |  2 |    |       | 13 | 15 | 14 |    |
+----+----+----+----+       +----+----+----+----+

$ 8puzzle.py -f2 -w1.9 15 14 13 12 11 10 9 8 7 6 5 4 3 1 2 0
# 76
Number of states enqueued = 2812200
2011
03.10

Mac Tips 3 – Startup Options

Startup keyboard shortcuts

Option

Display all bootable volumes
C

Start from a bootable disc (DVD, CD)
T

Start in FireWire target disk mode
N

Start from NetBoot server
X

Force Mac OS X startup (if non-Mac OS X startup volumes are present)
X

Force Mac OS X startup (if non-Mac OS X startup volumes are present)
Shift

Boot in Safe Mode. Effectively the same as passing “-x” in Kernel Flags, and causes most caches to be ignored by the booter.
Command-S

Boot in Single User Mode. Effectively the same as passing “-s” in Kernel Flags, and causes the system to boot to an interactive shell with no system services started.
Command-V

Boot in Verbose Mode. Effectively the same as passing “-v” in Kernel Flags, and causes the system to boot to verbose text logging before starting the graphical user interface.
3 2

Boot with the 32-bit kernel. Effectively the same as passing “arch=i386″ in Kernel Flags, and causes the system to prefer the 32-bit kernel on systems that would otherwise boot the 64-bit kernel.
6 4

Boot with the 64-bit kernel (if supported on this system). Effectively the same as passing “arch=x86_64″ in Kernel Flags, and causes the system to prefer the 64-bit kernel on systems that would otherwise boot the 32-bit kernel. If the 64-bit kernel is not supported, the option is ignored.

Hold down the mouse’s primary key during startup. On a two- or three-button mouse, the primary key is usually the left button. This shortcut will eject a CD or DVD from the optical drive.

Hold Command + Option + ‘p’ + ‘r’ during startup. This zaps the PRAM (Parameter RAM), an option that long-time Mac users will remember. Press and hold the key combination until you hear the second set of chimes. Zapping the PRAM returns it to its default configuration for display and video settings, time and date settings, speaker volume, and DVD region settings.

  • /Library/Preferences/SystemConfiguration/com.apple.Boot.plist
  • Mac OS X keyboard shortcuts
  • Mac OS X Startup Keyboard Shortcuts
  • 2011
    03.05

    Mac Tips 2

    Disable Spotlight in Mac OS X 10.6

    Disabling Spotlight in Snow Leopard is pretty easy, launch the Terminal and type the following command:

    sudo mdutil -a -i off

    This tells the Spotlight manager to disable all indexing on all volumes, the command will require your administrative password to execute.

    Re-enabling Spotlight in Mac OS X 10.6 Snow Leopard is just as easy, just reverse the command to:

    sudo mdutil -a -i on

    Now Spotlight indexing will be back on and work as usual.

    osxdaily

    sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
    sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
    
    2010
    12.02

    there was no one left to speak out

    Als die Nazis die Kommunisten holten,
    habe ich geschwiegen;
    ich war ja kein Kommunist.

    Als sie die Sozialdemokraten einsperrten,
    habe ich geschwiegen;
    ich war ja kein Sozialdemokrat.

    Als sie die Gewerkschafter holten,
    habe ich nicht protestiert;
    ich war ja kein Gewerkschafter.

    Als sie die Juden holten,
    habe ich geschwiegen;
    ich war ja kein Jude.

    Martin Niemöller

    2010
    11.25

    Mac Tips 1

    Prevent .DS_Store file creation on network stores

    defaults write com.apple.desktopservices DSDontWriteNetworkStores true
    

    Enable Remote Disc for MacBook Pro

    defaults write com.apple.NetworkBrowser EnableODiskBrowsing -bool true
    defaults write com.apple.NetworkBrowser ODSSupported -bool true
    

    Flush DNS Cache

    dscacheutil -flushcache
    

    Set hostname and prevent the DHCP server to change your host name

    scutil --set HostName
    

    Hide the file/folder from GUI Finder

    chflags hidden 
    chflags nohidden 
    

    Remove file attributes for Finder

    xattr -l 
    xattr -d com.apple.FinderInfo 
    

    Clean Up Finder’s “Open With” Menu

    # Go to your Home/Library/Preferences folder
    # Find “com.apple.LaunchServices” file and trash it (you can back it up if you want)
    # Test it out!
    lifehacker

    2010
    11.25

    VIM Tips 2

    :sp :split
    拆成上下两个显示区域

    :vsp :vsplit
    拆成左右两个显示区域

    CTRL-w CTRL-w 在显示区域间切换
    CTRL-w j 移到下面一个显示区域
    CTRL-w k 移到上面一个显示区域
    CTRL-w h 移到左面一个显示区域
    CTRL-w l 移到右面一个显示区域
    CTRL-w = 平分各个显示区域
    CTRL-w - 减小一行当前显示区域
    CTRL-w + 增加一行当前显示区域
    CTRL-w q 关闭当前显示区域
    CTRL-w r 向右(下)滚动显示区域
    CTRL-w R 向左(上)滚动显示区域

    2010
    11.25

    VIM Tips 1

    :set ignorecase
    通常你都会需要这个设置

    :set smartcase
    当搜索的时候使用大写字母将忽略上面的ignorecase设置

    :syntax on
    开启源代码高亮

    :set syntax=perl
    强制设定某一种语言的代码高亮,通常是根据文件后缀名自动匹配

    :h regexp<C-D>
    当敲入[CTRL-D]之后,会得到一个包含”regex“的帮助列表,用[TAB]键可以在列表中选择

    q:q/
    打开一个最近使用命令的小窗口;后一个为打开最近搜索指令的小窗口
    在小窗口敲[RETURN]键会执行所在行的命令。使用:quit退出小窗口。

    2010
    11.20

    iPhone应用真是太火了,我们一位同事利用安居客的API开发了一个查看周边房屋价格走势的iPhone应用,看上去还挺不错的,因此我们把它给转正了。经过调整用户界面,重构代码,然后重新以公司的帐号发布。

    这个正式的app正在苹果的审核中,很快就会出现在itunes上了。这里先给大家透露一下它的界面。
    更新:itune上的正式的app

      map  list  detail

    好了,下面说正题。这篇Blog的重点是招聘iPhone和Andriod的开发工程师。只要你对移动开发有很高的热情和很强的学习能力,不论你喜欢iOS还是Andriod平台我们都欢迎。如果你对移动开发已经很熟练了,或者在appstore上已经发布过应用,我们也是欢迎的。

    关于安居客,可以参考年初的这篇blog。当然,里面的各项数据已经out了,简单的x4应该和目前的差不多。

    如果你有兴趣,请尽快与我联系。另外,之前招聘的职位长期有效。

    2010
    06.04


    1 GR
    2 FOR I=1 TO 15:COLOR=I:HLIN 14,16 AT 11:VLIN 12,13 AT 13:VLIN 12,13 AT 17:HLIN 14,16 AT 14:VLIN 15,16 AT 13:VLIN 15,16 AT 17:HLIN 14,16 AT 17:HLIN 20,22 AT 11:VLIN 12,13 AT 19:VLIN 12,15 AT 23:HLIN 20,23 AT 14:PLOT 22,16:HLIN 19,21 AT 17:HLIN 15,17 AT 20:PLOT 14,21:VLIN 22,25 AT 13:HLIN 13,17 AT 23:VLIN 24,25 AT 17:HLIN 14,16 AT 26:PLOT 21,21:PLOT 20,22:PLOT 19,23:HLIN 19,23 AT 24:VLIN 20,26 AT 22:NEXT I:GOTO 2

    复制上面的代码,并粘贴到下面这个网站,然后点击”Run”按钮
    www.calormen.com/applesoft/

    看看我在VirtualII上的运行结果