42区漫游指南#

Don’t panic ( 不要恐慌 )#

本书网址 : book.42qu.com

请您先阅读 常见问题

网页前端#

初学者 请先依次阅读 参考书籍 » 入门篇 中的资料

参考书籍#

入门篇#
  1. 网页设计师 , 初学者可以从其中 » 循序渐进 章节开始自己的学习之旅
  2. HTML中文手册
  3. CSS中文手册
  4. CSS3 系列教程
  5. Javascript教程
  6. 15天学会jquery
  7. jquery中文手册

概述#

作者:张沈鹏 zuroc.42qu.com
HTML#

首先推荐开发工具EditPlus , 参见 工具 -> Windows -> EditPlus

基本结构#

一个最基本的HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body></body>
</html>

HTML5的写法更简单 , Google首页就是这样写的

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body></body>
</html>

注: 我喜欢简单的写法

body#
元素类型#

具体详情 见 HTML中文手册

使用Firebug可以快速学习现有页面上有哪些元素 , 参见 Firebug 查找 / 编辑 元素

CSS#
Reset Css#

每每有新项目,第一步就是应当使用一个reset.css来重置样式。

  1. Reset CSS研究(八卦篇)
  2. KISSY CSS Reset
大布局#
div 的 布局#
  1. 居中 margin:auto
  2. 左浮动 float:left
  3. 右浮动 float:right
几栏布局#
  1. Grids Layout for Taobao

小样式#
CSS3#

系统学习

CSS3 系列教程 , 内容提要

  1. 圆角
  2. 阴影
  3. 多背景图
  4. 渐变色 渐变色生成器

实际运用

CSS3渐变按钮

实例学习 - 仿造 点名时间 写页面#
  1. 页面原型
  2. 一步一步仿写
如何自学 ?#
  1. 首先 点此打包下载 源代码

  2. 布局学习的目录是 /book/file/css_js_realfex/layout

  3. 样式学习的目录是 /book/file/css_js_realfex/style

  4. 点此下载 Beyond Compare 3 , 对比每一步文件的差异学习
    _images/bycompare.png
  5. 自己新开一个文件 , 对照页面尝试编写

  6. 可以使用 Firebug 查看每一步的细节样式

Javascript#
实例学习 - 仿造 点点网 写注册页面#
  1. 点点网 注册页面的原型
  2. 一步一步仿写Javascript
CDN#

新浪 公共资源

http://sae.sina.com.cn/?m=devcenter&catId=147

公共资源包含Jquery, Mootools, Prototype,YUI 等通用JS/CSS Framework;您可以通过地址直接引用。

公共资源前端采用CDN技术,节点分布在全国各地;用户可以就近取得资源内容, 提升您的应用速度。

赶快使用公共资源来给您的应用加速吧!

工具#

Firefox 插件#
FireBug#
查找 / 编辑 元素# _images/firebug_insert_elem.png

使用Firebug可以查看学习现有页面上有哪些元素

点击 编辑 , 可以直接修改现有页面上的内容 ( 比如 : 把新浪微博的粉丝数修改为9999999 哈哈 )

右侧, 样式 , 可以直接编辑css的属性

查看对象的盒模型# _images/firebug_box.png
Scrapbook#
  1. 静态化 Ajax 生成的页面
  2. 保存 Firebug 编辑过的页面
  3. 抽取网页上的图片
  4. 抽取页面的部分样式
LiveHTTPHeaders : http请求抓取、重发、模拟工具#

可有筛选的监测所关心的http请求。

官方网站:http://livehttpheaders.mozdev.org/

FireMobileSimulator : 模拟手机浏览器#

https://addons.mozilla.org/ja/firefox/addon/firemobilesimulator/

Linux 基础#

Linux 最初是 Linus Torvalds 于 1991 年在大学写的操作系统。今天,Linux 拥有了优秀的开发团队、庞大的用户社区和成功的商业模式。虽然在桌面市场表现不佳,但是在 Linux 服务器(Top 10 网站中的六家)、科学计算(Top 500 中的 459 台)、嵌入式(大量的路由设备、工业控制产品)以及新兴的移动设备(Android)领域都取得巨大的成功。

Linux 是现今最成功的自由软件之一。

SSH 登录 Linux服务器 流程说明#

作者:陈庚 huhuchen.42qu.com
Xshell : 极好用的免费SSH客户端#

点此下载 Xshell

创建session#

安装好xshell后,打开软件,点击菜单栏“File”中的“new”,将出现下图所示弹窗,填写相应信息。其中Host为邮件中所给的主机ip地址(name栏可以不用修改,但一般为便于在xshell中区分不同的主机,自己一般会修改为“用户名@主机”,也可以用“用户名@42qu”),然后点击“ok”。

首次登录
登录#

在随后弹出的弹窗中选择自己创建的帐号,点击“connect”,在弹出窗口中输入邮件中提供的用户名,新窗口中选择“keyboard Interactive”

并确定,最后输入邮件中提供的密码,即可登录到自己的vps中。

  1. _images/login1.png
  2. _images/login2.png
  3. _images/login3.png
设置显示编码#

简单设置一下xshell的字符显示,在下图所示的导航按钮中,勾选“UTF-8”。

_images/encoding.png

顺便可以设置下字体

_images/xshell_ft.png

如果觉得粗体看着碍眼, 那么可以修正下显示设置

  1. _images/xshell_font_btn.png
  2. _images/xshell_font.png
配置密钥登录 , 无需每次输入密码#

为避免每次登录vps都需要重复输入用户名和密码的步骤,可以通过生成.ssh/authorized_keys来减少麻烦。

执行:

cd ~

命令,来到home(家)目录

执行:

ssh-keygen

命令 , 然后按两次回车, 生成密钥

执行:

cd  .ssh

进入.ssh目录

执行:

cat id_rsa.pub >> authorized_keys

将把当前目录下

id_rsa.pub中的数据拷贝一份到新建的authorized_keys档案中。

_images/makekeys.png

点击导航中的“new file transfer”图标,如下图所示。

_images/filetransfer.png

弹出窗口中忽视警告,确定后输入密码,在.ssh目录下执行“get id_rsa”命令,id_rsa将被保存到下图红线所示的本地目录中。

_images/getkeys.png

在xshell菜单栏中依次点击“File”->“open”,选中你的session用户,并点击“Properties”,如下图所示。

_images/reset1.png

做下图所示修改,点击“Browse”按钮。

_images/reset2.png

点击import按钮,选择id_rsa,之后一路确定,再次登录是就可以不用再输入用户名和密码了。

_images/reset3.png
克隆代码#

重新登录后,为了方便学习各种命令; 我们可以首先克隆一份 42qu.com 的源代码, 执行:

hg clone https://bitbucket.org/zuroc/zpage

等上十分钟 , 会在当前目录下生成新目录zpage,其中包括了项目的所有代码,如图所示。

_images/clone.png
安装 virtualenv#

首先运行

virtualenv .

然后修改 ~/.bash_profile 如下

[[ -f ~/.bashrc ]] && . ~/.bashrc
export PATH=$HOME/bin:$HOME/sbin:$PATH:/usr/sbin:/sbin

再运行

source ~/.bash_profile

再运行

pip install setuptools --upgrad

然后就可以使用 pip 或者 easy_install 安装python的库了

预习资料#

必读:

  1. http://mirrors.tuna.tsinghua.edu.cn 阅读镜像列表中的描述。
  2. 在 Linux主机 上运行 vimtutor 。在上课前请熟悉 Lesson 1 到 Lesson 3 的内容,并泛读余下的内容。特别是能熟练地使用 hjkl
  3. 在 Linux主机 上运行 man 1 intro ,阅读。
  4. http://wiki.tuna.tsinghua.edu.cn/Salon/2011-10-25 Cheer Xiao 在清华校内的一次技术沙龙。请下载它的 presentation 并阅读。如果你觉得看不懂,可以看过下面的一些泛读资料后再读。

泛读和参考之英文版:

  1. http://www.ubuntupocketguide.com/download_main.html Ubuntu Pocket Guide. 提供在线 PDF 版本(Google Books) 和下载版本。阅读 Chapter 5。
  2. Linux Scripting with Bash 全书都可以读。
  3. 在 Linux主机 上运行 pinfo coreutilspinfo 使用方向键就能导航。

下面给出中文参考资料,和上面的英文版内容覆盖是重叠的。如果你能顺利地读下英文版,就不需要了:

  1. 鸟哥的 Linux 私房菜 适合初学者的阅读材料。你可以跳过前几章,从“档案属性与目录配置”开始阅读。
  2. Linux系统命令及其使用详解
  3. http://forum.ubuntu.org.cn/viewforum.php?f=21 Ubuntu 中文论坛的其它区也有质量较高的资源。

Gentoo 发行版#

软件安装 - 包管理#
eix : 搜索软件#

安装eix

emerge eix
  1. 软件包搜索(搜索名字):

    eix key_word
    
  2. 软件包搜索(搜索内容):

    eix -S key_word
    
  3. 与本地portage同步

    eix-update
    
  4. 把emerge –sync 与 eix-update 一并做成

    eix-sync
    
  5. 在某个具体类别中搜索软件名

    eix -C media-video cam
    
  6. 在已安装包中搜索软件名

    eix -I key_word
    
emerge : 安装软件#
  1. 安装软件

    emerge package_name
    
  2. 安装被mask的软件 (如firefox)

    emerge -av --autounmask-write=www-client/firefox-bin-8.0
    
  3. 更新软件并更新它直接依赖的其它软件包

    emerge -u package_name
    
  4. 更新一个软件并更新它依赖的软件包以及它们依赖的所有软件包, 这里大写的D相当于–deep

    emerge -uD package_name
    
  5. 软件包卸载:

    emerge -C package_name
    
  6. 清除所有失去依赖关系的软件包:

    emerge -c
    
equery : 查看已安装的软件#

安装此工具: emerge gentoolkit

  1. 列出所有已安装包:

    equery list
    

    简写:

    equery l
    
  2. 查看已安装包装了哪些内容

    equery files package_name
    

    简写

    equery f package_name
    
  3. 查看一个程序foo隶属于哪个包

    equery belongs foo
    

    简写:

    equery b foo
    
  4. 查看哪些包依赖于package_name

    equery depends package_name
    

    简写

    equery d package_name
    
  5. 查看已安装包用了哪些USE

    equery uses package_name
    

    简写:

    equery u package_name
    

Crontab命令简介#

crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。

该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。

crontab文件#

该文件通常存放于/etc或者/etc之下的子目录中,而这个文件只能由系统管理员来修改。

crontab文件的每一行均遵守特定的格式,由空格或tab分隔为数个领域,每个领域可以放置单一或多个数值。

语法介绍#

  使用权限: root用户和crontab文件的所有者

crontab格式语法:

crontab [-e [UserName]|-l [UserName]|-r [UserName]|-v [UserName]|File ]

  参数:

-e [UserName]: 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe)

  -r [UserName]: 删除目前的时程表

  -l [UserName]: 列出目前的时程表

  -v [UserName]:列出用户cron作业的状态

时程表的格式如下:

  f1 f2 f3 f4 f5 program

  其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的程式。

  当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程式,其余类推

  当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其余类推

  当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,其余类推

  当 f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行,f2 为 a, b, c,... 时表示第 a, b, c...个小时要执行,其余类推

  使用者也可以将所有的设定先存放在档案 file 中,用 crontab file 的方式来设定时程表。

  由于unix版本不一样,所以部分语法有差别,例如在hp unix aix 中设定间隔执行如果采用*/n 方式将出现语法错误,在这类unix中 ,间隔执行只能以列举方式,详请见例子。

使用方法#

  用VI编辑一个文件 cronfile,然后在这个文件中输入格式良好的时程表。编辑完成后,保存并退出。

  在命令行输入   $: crontab cronfile

  这样就将cronfile文件提交给c r o n进程,同时,新创建cronfile的一个副本已经被放在/var/spool/cron目录中,文件名就是用户名。

  例子:

每月每天每小时的第 0 分钟执行一次 /bin/ls :

0 * * * * /bin/ls

在 12 月内, 每天的早上 6 点到 12 点中,每隔 20 分钟执行一次 /usr/bin/backup :

*/20 6-11 * 12 * /usr/bin/backup

周一到周五每天下午 5:00 寄一封信给 alex_mail_name :

0 17 * * 1-5 mail -s “hi” alex_mail_name < /tmp/maildata

每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分....执行 echo “haha”

20 0-23/2 * * * echo “haha”

晚上11点到早上8点之间每两个小时,早上8点

0 23-7/2,8 * * * date

  在hp unix,中,每20分钟执行一次,表示为:0,20,40 * * * * 而不能采用*/n方式,否则出现语法错误

注意:

  1. 当程式在你所指定的时间执行后,系统会寄一封信给你,显示该程式执行的内容,若是你不希望收到这样的信,请在每一行空一格之后加上 > /dev/null 2>&1 即可。

  2. %在crontab中被认为是newline,要用来escape才行。比如crontab执行行中,如果有”date +%Y%m%d”,必须替换为:”date +%Y%m%d”

创建crontab#

  在考虑向cron进程提交一个crontab文件之前,首先要做的一件事情就是设置环境变量EDITOR。cron进程根据它来确定使用哪个编辑器编辑crontab文件。99 %的UNIX和LINUX用户都使用vi,如果你也是这样,那么你就编辑$HOME目录下的.profile文件,在其中加入这样一行:

  EDITOR=vi; export EDITOR

  然后保存并退出。

  不妨创建一个名为<user>cron的文件,其中<user>是用户名,为了提交你刚刚创建的crontab文件,可以把这个新创建的文件作为cron命令的参数:

  $ crontab davecron

  现在该文件已经提交给cron进程,同时,新创建文件的一个副本已经被放在/var/spool/cron目录中,文件名就是用户名(即,dave)。 列出crontab文件 —————–   为了列出crontab文件,可以用:

  $crontab -l

编辑crontab文件#

  如果希望添加、删除或编辑crontab文件中的条目,而EDITOR环境变量又设置为vi,那么就可以用vi来编辑crontab文件,相应的命令为:

  $ crontab -e

  可以像使用vi编辑其他任何文件那样修改crontab文件并退出。

删除crontab文件#

  为了删除crontab文件,可以用:

  $ crontab -r

恢复丢失的crontab文件#
  如果不小心误删了crontab文件,假设你在自己的$HOME目录下还有一个备份,
那么可以将其拷贝到/var/spool/cron/<username>,其中<username >是用户名。 如果由于权限问题无法完成拷贝,可以用:

  $ crontab <filename>

  其中,<filename>是你在$HOME目录中副本的文件名。

crontab中的输出配置#

  crontab中经常配置运行脚本输出为:>/dev/null 2>&1,来避免crontab运行中有内容输出。

  shell命令的结果可以通过‘> ’的形式来定义输出

  /dev/null 代表空设备文件

  > 代表重定向到哪里,例如:echo “123” > /home/123.txt

  1 表示stdout标准输出,系统默认值是1,所以”>/dev/null”等同于”1>/dev/null”

  2 表示stderr标准错误

  & 表示等同于的意思,2>&1,表示2的输出重定向等同于1

  那么重定向输出语句的含义:

  1>/dev/null 首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,不显示任何信息。

  2>&1 表示标准错误输出重定向等同于标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。

讲义#

  • Unix - what defines Unix?
    • 统一的名字空间
      • 一切皆文件; file descriptor, fd
      • mount(1), devfs - udev(7)
      • 虽然在网络和 GUI 编程方便被背弃——BSD 风格套接字
    • 标准化的命令行交互环境
    • 简短的系统调用名字……
    • Plan 9 from Bell Labs
      • 真正统一的 API 和名字空间
      • /proc 和 /sys 对 Unix 的回归
  • Linux
    • 和 *BSD 一起,最流行的自由的 Unix 的变体
    • 最为成功的自由软件项目之一
    • GNU/Linux
    • 各种 distro
      • Redhat / CentOS / Scientific; Fedora
      • SUSE; openSUSE
      • Debian; Ubuntu
      • Arch
      • Gentoo
  • Shell
    • 概览:历史、各种乱七八糟的变种(bourne shell, csh; tcsh, bash, zsh)
    • POSIX, POSIX shell, POSIX 工具集, man 1p
    • POSIX ~= Unix (~=: 约等于)
  • shell 基本命令和工具
    • 命令:分词和展开; intro(1)
    • 内建命令 cd, pwd, exec, exit, type
    • 目录操作 ls, mkdir, rmdir
    • 文件操作 touch, mv, cp, chmod, chown
      • mod bit: [ugo]rwx, ls -l
    • 通用选项 -R, -f, -i (Thanks to POSIX)
    • . 和 ..;dotfile
    • man, manpage section
      • Linux has 1. user command 2. syscall 7. misc 8: admin command etc.
      • ascii(7)
      • section 1p and 3p (p for POSIX)
    • 很多常用工具都是对系统调用的封装
      • cd(1) - chdir(2)
      • chmod(1) - chmod(2)
      • mkdir(1) - mkdir(2)
      • stat(1) - stat(2)
      • ...
  • 文本工具
    • cat (文本连接;管道中的单位元), tee (文本流复用)
    • grep (过滤 filter), sed (映射 map)
    • Unix 正则表达式(BRE, ERE)
      • BRE 和 ERE 表达力是一样的……只是语法不同
      • BRE: first-class meta-characters: ^ $ [ ] . *
      • ERE: grep -E, sed -r
    • diff
    • 用例: sed -i 和 diff
  • I/O 重定向和管道
    • stdin(fd=0), stdout(fd=1), stderr(fd=2)
    • 简单重定向 demo
    • 用例:随机噪音生成器:: cat /dev/urandom | base64 | seq ‘10q’
    • 用例: tar c file1 file2 > a.tartar x < a.tar
  • shell 编程
    • 真与假 (main() 的返回值)
    • && 和 ||
    • 控制流:if, for, while
    • shell 语法原则“只有第一个单词是特殊的”
    • 变量赋值和引用: =$
    • Quoting hell: POSIX shell 和后 POSIX shell
      • POSIX shell 中未加引号的变量可能展开成多个单词
      • zsh 中一个变量只展开为一个单词
    • $()\`\`
  • zsh
    • Mr. Everything
      • 兼容一切!
      • 25696 行的 manpage
      • Evil but practical for interactive use
    • Tab 补全 demo
      • 菜单
      • a.b -> ablah.bblah
    • 语法高亮
    • RPS:右侧提示符
  • sysadmin 常用工具
    • sudo
    • ack
      • 插播 shell demo: 计算 ack 源码实际行数:: cat $(which ack) | sed -r ‘/^s*}?$/d’ | wc -l
    • htop, ps
    • ping, mtr
    • ip addr/route, iptables (Linux only)
    • lsof, lsof -i
    • 各个 distro 的包管理器
  • Vi 基础
    • Bill Joy 和他的键盘
    • 有模式编辑器:丰富而简短的命令
    • 方向键 hjkl;跳转命令 G gg
    • 动宾结构的编辑命令 dw cW c$ dd
    • 数字修饰符
    • 模式穿梭命令 i a Esc ^C
    • Ex 命令 :wq :s
    • 搜索 / 和 ?
  • Vim
    • 丰富而复杂的选项
    • 很挫的脚本语言 (We’re stuck with it)
      • 丰富的插件 (不过当然比不上 Emacs 啦)
    • 非常完整的文档 + :help [keyword]
    • 分屏 + :split - Think about fork(3) + :edit - Think about exec(3) + :split [fname] + :vsplit + 甚至还有标签页 (:tabnew, gt, gT)
    • 语法高亮
    • 代码折叠 (zo zc ...)
    • tag 跳转 (ctags -R .)
    • Tab 补全 (我不用……)
    • 标准插件:文件管理器 netrw
    • 第三方插件: zencoding

Python 基础#

讲义#

  • Python 之零

    • Guido van Rossum (CWI, Google)
    • Google 的主力语言之一 (besides Java and C++)
    • 当今最干净的编程语言之一
    • 表达力强大,可惜性能不足
      • 八卦:高性能的动态语言……Lua 和 JavaScript
    • 启发:Perl (基本上都是反例), ABC (CWI)
    • Zen of Python: import this
  • Python 之一

    • Python 2 vs Python 3 (stick to py2 for now)
    • Interactive shell (REPL Read-Eval-Print Loop)
    • ipython, bpython
      • ipython 的 ?
  • 动态类型:抛弃模板

    • 相加的例子……
    • def 关键字
  • 内建数据类型和操作

    • int and long, float, str
      • long: 内建高精度整数运算
      • complex (j)
    • + - * /
      • / 在 py2 和 py3 中的差异
      • 没有 int/str 的隐式转换
      • str * int
    • type() 内建函数
    • dict, list, tuple, set
      • 容器都是 heterogeneous 的
      • 类型转换:class as callable
      • callable() 内建函数
      • 多返回值(tuple)
      • del
    • dir() 内建函数
    • magical underscore (__xx__)
      • like meta-table in Lua
    • 格式化操作符 %
      • 万能的 %s%r
      • strrepr__str____repr__
  • 基本语法结构

    • 基于缩进(和冒号)的层级结构
    • “Words are better than punctuations”
  • 基本控制结构

    • 不需要多余的圆括号

    • if, while (nothing special)

    • for - 只有 generic for。模拟传统数值 for:

      for i in range(n):
      
    • break, continue

    • 占位符 pass

    • 再提 def

      • 默认参数、具名参数、变长参数表(*argli)、变长具名参数表(**argdi)
      • docstring __doc__
    • 生成器(不对称协程, asymetric coroutine) yield 关键字

    • 避免名字和关键字冲突:末尾加 _

  • 名字空间和模块

    • importfrom x import y
    • import __builtin__
    • 全局名字空间和局部名字空间
      • 赋值即绑定
      • globals()locals()
      • global 关键字
    • 控制结构不引入内层名字空间……demo
    • 闭包 (closure)
    • 变量的引用语义
      • 不可变对象(数值类型、str, tuple)
      • id() 内建函数
      • 小对象池
      • dict 的键须为不可变对象; hash__hash__()
  • 模块层次

    • sys.path
    • module.py or module/__init__.py
  • OO 初探:内建类型的方法
    • str 内建方法
      • str 是不可变对象。So...
    • list 内建方法
      • 重载的 + 和 *
    • dict 内建方法
  • OO 之类定义
    • class 关键字; __init__
    • 对象方法, self
      • 和 Lua 的不同
      • 被施咒的函数 (bound method)
    • 私有成员 __foo
      • 内部原理:名字修饰
      • No true constants, no true private members
    • 类成员 (shared member, static member)
      • Functions? No way...
  • OO 之类层次
    • 继承;根类型 object
    • 没有隐含的 init 传递
      • 手工调用的父类 __init__ (Explicit is better than implicit)

Python 的闭包和装饰器#

翻译: TheLover_Z

Part I#

原文地址: http://blaag.haard.se/Python-Closures-and-Decorators–Pt–1/

回想起来,当初我做出了错误的选择,把 Python 的课程削减到了4个小时以至于把装饰器的部分搞砸了,我答应大家我稍后会对闭包和装饰器做一个更好的解说 —— 我是这么打算的。

函数也是对象。实际上,在 Python 中函数是一级对象——也就是说,他们可以像其他对象一样使用而没有什么特别的限制。这给了我们一些有趣的选择,我会由浅到深解释这个问题。

关于函数就是对象的一个最常见的例子就是 C 中的函数指针;将函数传递到其他的将要使用它的函数。为了说明这一点,我们来看看一个重复函数的实现 —— 也就是,一个函数接受另外一个函数以及一个数字当作参数,并且重复调用指定函数指定次数:

>>> #A very simple function
>>> def greeter():
…     print("Hello")

>>> #An implementation of a repeat function
>>> def repeat(fn, times):
…     for i in range(times):
…         fn()

>>> repeat(greeter, 3)
Hello
Hello
Hello
>>>

这种模式在很多情况下都有用 —— 比如向一个排序算法传递比较函数,向一个语法分析器传递一个装饰器函数,通常情况下这些做法可以使一个函数的行为 更专一化 ,或者向已经抽象了工作流的函数传递一个待办的特定部分(比如, sort() 知道怎么排序, compare() 知道怎么比较元素)。

函数也可以在其他函数的内部声明,这给了我们另一个很重要的工具。在一般情况下,这可以用来隐藏实用函数的实现细节:

>>> def print_integers(values):
…     def is_integer(value):
…         try:
…             return value == int(value)
…         except:
…             return False
…     for v in values:
…         if is_integer(v):
…             print(v)

>>> print_integers([1,2,3,"4", "parrot", 3.14])
1
2
3

这可能是有用的,但它本身并不算是个强大的工具。相比函数可以当作参数被传递而言,我们可以将它们包装(wrap)在另外的函数中,从而向已经构建好的函数增加新的行为。一个简单的例子是向一个函数增加跟踪输出:

>>> def print_call(fn):
…     def fn_wrap(*args, **args): #take any arguments
…         print ("Calling %s" % (fn.func_name))
…         return fn(*args, **kwargs) #pass any arguments to fn()
…     return fn_wrap

>>> greeter = print_call(greeter) #wrap greeter
>>> repeat(greeter, 3)
Calling fn_wrap
Hello
Calling fn_wrap
Hello
Calling fn_wrap
Hello
>>>
>>> greeter.func_name
'fn_wrap'

正如你看到的那样,我们可以使用带日志的函数来替换掉现有函数相应的部分,然后调用原来的函数。在例子的最后两行,函数的名字已经反映出了它已经被改变,这个改变可能是我们想要的,也可能不是。如果我们想包装一个函数同时保持它原来的名字,我们可以增加一行 print_call 函数,代码如下:

>>> def print_call(fn):
…     def fn_wrap(*args, **kwargs): #take any arguments
…         print("Calling %s" % (fn.func_name))
…         return fn(*args, **kwargs) #pass any arguments to fn()
…     fn_wrap.func_name = fn.func_name #Copy the original name
…     return fn_wrap

因为这是一个很长的话题,我明天会来更新第二部分,我们会讲讲闭包,偏函数(partial),还有(终于到它了)装饰器。

至此,如果这些你之前全部没有接触过,可以先用 print_call 函数作为基础,来创建一个能够在正常调用函数之前先打印出这个函数名字的一个修饰器。

Part II#

原文地址: http://blaag.haard.se/Python-Closures-and-Decorators–Pt–2/

在第一部分中,我们学习了以函数作为参数调用其他的函数,还有嵌套函数,最终我们把一个函数包装在另外的函数中。我们先把第一部分的答案给出:

>>> def print_call(fn):
…     def fn_wrap(*args, **kwargs):
…         print("Calling %s with arguments: \n\targs: %s\n\tkwargs:%s" %fn.__name__, args, kwargs))
…         retval = fn(*args, **kwargs)
…         print("%s returning '%s'" % (fn.func_name, retval))
…         return retval
…     fn_wrap.func_name = fn.func_name
…     return fn_wrap

>>> def greeter(greeting, what='world'):
…     return "%s %s!" % (greeting, what)

>>> greeter = print_call(greeter)
>>> greeter("Hi")
Calling greeter with arguments:
    args: ('Hi',)
    kwargs:{}
greeter returning 'Hi world!'
'Hi world!'
>>> greeter("Hi", what="Python")
Calling greeter with arguments:
    args: ('Hi',)
    kwargs:{'what': 'Python'}
greeter returning 'Hi Python!'
'Hi Python!'
>>>

这稍微有那么点儿用了,但它可以变的更好!你可能听说过或者没有听说过*闭包*,你可能听说过成千上万种闭包定义中的某一种或者某几种 —— 我不会那么挑剔,我只是说闭包就是一个捕捉了(或者关闭)非本地变量(自由变量)的代码块(比如一个函数)。如果你不清楚我在说什么,你可能需要进修一下 CS 的相关课程,但是不要担心 —— 我会给你演示例子。闭包的概念很简单:一个可以引用在函数闭合范围内变量的函数。

比如说,看一下这个代码:

>>> a = 0
>>> def get_a():
…     return a

>>> get_a()
0
>>> a = 3
>>> get_a()
3

正如你看到的那样, get_a 函数可以取得 a 的值,并且可以读取更新后的值。然而这里有一个限制 —— 被捕获的变量(captured variable,下同)不能被写入。

>>> def set_a(val):
…     a = val

>>> set_a(4)
>>> a
3

为什么会这样?由于闭包不能写入任何被捕获的变量, a = val 这个语句实际上写入了本地变量 a 从而隐藏了模块级别的 a ,这正是我们想写入的内容。为了解决这个限制(也许这并不是一个好主意),我们可以用一个容器类型:

>>> class A(object): pass

>>> a = A()
>>> a.value = 1
>>> def set_a(val):
…     a.value = val

>>> a.value
1
>>> set_a(5)
>>> a.value
5

因此,我们已经知道了函数从它的闭合范围内捕捉变量,我们最终可以接触到有趣的东西了,我们先实现一个偏函数(partial,下同)。一个偏函数是一个你已经填充了部分或者全部参数的函数的实例;比如说你有一个存储了用户名和密码的会话,和一个查询后端的函数,这个函数有不同的参数但是*总是*需要身份验证。与其说每次都手动传递身份验证信息,我们可以用偏函数来预填充那些信息。

>>> #Our 'backend' function
… def get_stuff(user, pw, stuff_id):
…     """Here we would presumably fetch data using the
…     credentials and id"""
…     print("get_stuff called with user: %s, pw: %s, stuff_id: %s" % (user, pw, stuff_id))
>>> def partial(fn, *args, **kwargs):
…     def fn_part(*fn_args, **fn_kwargs):
…         kwargs.update(fn_kwargs)
…         return fn(*args + fn_args, **kwargs)
…     return fn_part

>>> my_stuff = partial(get_stuff, 'myuser', 'mypwd')
>>> my_stuff(3)
get_stuff called with user: myuser, pw: mypwd, stuff_id: 3
>>> my_stuff(67)
get_stuff called with user: myuser, pw: mypwd, stuff_id: 67

偏函数可以用在许多地方来消除代码的重复。当然,你没有必要自己手动实现它,只需要 from functools import partial 就可以了。

最后,我们来看看函数装饰器(未来可能有类装饰器)。函数装饰器接收一个函数作为参数然后返回一个新的函数。听起来很熟悉吧?我们已经实现过一个 print_call 装饰器了。

>>> @print_call
… def will_be_logged(arg):
…     return arg*5

>>> will_be_logged("!")
Calling will_be_logged with arguments:
    args: ('!',)
    kwargs:{}
will_be_logged returning '!!!!!'
'!!!!!'

使用@符号标记是一个很方便的方法。

>>> def will_be_logged(arg):
…     return arg*5

>>> will_be_logged = print_call(will_be_logged)

但是如果我们想要确定装饰器的参数呢?在这种情况下,作为装饰器的函数会接收参数,并且返回一个包装(wrap)了装饰器函数的函数。

>>> def require(role):
…     def wrapper(fn):
…         def new_fn(*args, **kwargs):
…             if not role in kwargs.get('roles', []):
…                 print("%s not in %s" % (role, kwargs.get('roles', [])))
…                 raise Exception("Unauthorized")
…             return fn(*args, **kwargs)
…         return new_fn
…     return wrapper

>>> @require('admin')
… def get_users(**kwargs):
…     return ('Alice', 'Bob')

>>> get_users()
admin not in []
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 7, in new_fn
Exception: Unauthorized
>>> get_users(roles=['user', 'editor'])
admin not in ['user', 'editor']
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 7, in new_fn
Exception: Unauthorized
>>> get_users(roles=['user', 'admin'])
('Alice', 'Bob')
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 7, in new_fn
Exception: Unauthorized

就是这样。你现在会写装饰器了,也许你会用这些知识去写面向方面(aspect-oriented)的编程。加入 @cache, @trace, @throttle 都是微不足道的(在你添加 @cache 之前,一定要检查 functools ,如果你用的是 Python 3 的话!)

拓展阅读#

本部分由 张沈鹏 补充

Python正则表达式操作指南#

点此阅读 Python正则表达式操作指南

常用工具#

windows常用工具#

360软件管家 可以快速安装以下大部分程序

Launchy : 快速启动程序#

Launchy 可以使你快速的调用你电脑中的程序快捷方式,而且很智能,使用起来很智能

快捷键 Alt + 空格

可以把自己的绿色软件目录, 也添加到它的监控中去

http://www.launchy.net/

ColorMania : 屏幕取色#

点此下载 ColorMania

Everything : 文件名搜索软件, 其速度之快令人震惊#

Everything 是速度最快的文件名搜索软件。

其速度之快令人震惊,百G硬盘几十万个文件,可以在几秒钟之内完成索引;文件名搜索瞬间呈现结果。

点此下载 Everything

EditPlus : 文本编辑器 , 写网页很方便#
  1. 设置新建文件的默认编码为UTF-8

    Document -> Parmannet Setting -> File
    
  2. 设置默认显示HTML工具栏

    Document -> Parmannet Setting -> File
             -> Setting & syntax -> Show HTML toolbar
    
  3. 创建新的HTML文件

    快捷键 Ctrl+Shift+N
    
  4. 快捷键 Ctrl + B 可以 在 浏览器模式 和 编辑模式中切换

Snagit : 截图软件#

点此下载 Snagit

基本介绍:

强大的截图编辑工具,能够在所截获的图片上添加文字或图示说明,并保存为特定的图片格式。

解压后先运行 Install.reg 即可绿化安装

SftpDriver : 挂载SSH服务器到本地硬盘#

点此下载 SftpDriver

  1. 基本介绍

    可以把SSH服务器映射成Windows本地硬盘的工具,用户可以方便地在本地进行删除,编辑等操作,就像在本地硬盘上一样方便.

  2. 使用说明:

    安装好软件后,填写下图中红色部分,依次是驱动名(本地映射的硬盘名将是此名)、服务器域名或ip、服务器登录用户名、服务器登录密码,之后点击connect。

    sftpdriver连接信息

    最终在“我的电脑”里将出现下图所示映射硬盘,点击进入,每次上传文件只需要将本地文件复制到该硬盘下相应目录下即可。

    sftpdriver映射成功
IEtester : 测试各个版本的IE浏览器#

http://www.my-debugbar.com/wiki/IETester/HomePage

Beyond Compare : 对比文件的差异#

点此下载 Beyond Compare 3

MySQL GUI Tools 5.0 : MySQL 管理#

点此下载 MySQL GUI Tools 5.0

Git#

  1. Git cheat sheets

  2. Git 使用流程

  3. 《Pro Git》中文译文

  4. github用法指南

  5. Git资料收集 打包下载 , 内容清单如下
    1. 最好的git中文教程.pdf
    2. 使用git版本管理手册.docx
    3. TortoiseGit使用入门.doc
    4. TortoiseGit日常使用指南.pdf
    5. ProGit 中文版.pdf
    6. git中文资料.pdf
    7. Git中文教程.pdf
    8. Git一分钟上手.pdf
    9. git手册.pdf
    10. git使用总结.doc
    11. GIT使用体会.pdf
    12. Git入门教程.doc
    13. git-tutor.pdf
    14. Git+使用教程.pdf
    15. Git_用户手册.docx
  6. git-svn

  7. 如何在Github上创建新项目

42qu.com 网站开发#

42qu.com 入门指南 : 程序员 篇#

作者:张沈鹏 zuroc.42qu.com

有任何问题 , 欢迎加我微信 : zsp042

前言#

42qu.com是一个开源项目 , 开源的初衷如下 :

看了 吉米·威尔士关于维基百科诞生的演讲

再一次被开源的力量所震撼 ,我觉得, 我应该也去搞一个NB的开源项目

因为发现很多初学者用python写网站没经验, 写出来的网站比较卡, 让我很痛心,于是这一次, 我又开始了一个坑 ,打算基于Python的Tornado, 打造一套可以抗千万PV的SNS/微博/轻博客的开源基础框架

让以后Python程序员写SNS, 省去很重复开发的工作 - 比如登录, 比如头像, 比如相册, 比如日记, 比如等等等...

对了 , 你也许会对下面这个感兴趣 - 42qu.com 开源项目 代码贡献者 奖励方案

欢迎参与, 前端, 美工, 程序员, 都可以!

申请开发权限#

我们提供了一个能很方便运行42qu.com代码的线上开发服务器

因为资源极度有限 , 此开发服务器仅对有能力贡献代码的开发者开放

首先, 在 bitbucket 上提交 issue

https://bitbucket.org/zuroc/zpage/issues/new

向管理员申请开发服务器的访问权限

申请中请注明

  1. 在42qu.com的主页地址

  2. 期望认领的任务

    • 方式 1 :

      http://42qutk.sinaapp.com/project-task-1.html 认领未分配的任务 (请附上任务编号)

      在任务被认领后, 我们将会给出更详尽的需求文档 :)

    • 方式 2 :

      如果你有自己想在42qu.com上实现的功能

      可以在bitbucket的issue中做详细说明

然后申请加入42qu.com开发者的 Google Groups my42

申请理由为刚刚在bitbucket上创建的issue的链接地址

管理员确认后 , 你会收到一份邮件

邮件里面会给出你所分配到的开发域名

注册开发域名#

https://www.dnspod.cn/ 注册一个帐号 , 绑定邮件里面提到的域名

_images/dnspod.png

然后去 http://dot.tk/ 注册一个免费的顶级域名 (请先创建帐号, 然后注册)

_images/tk.png

选择用自己的DNS服务器

_images/tk2.png

把 dnspod 的 namesever 地址copy过来

_images/dnspod_nameserver.png

最后在 dnspod 上 , 追加两个域名解析, 一个什么也不需要填 , 一个填写* , 都指向开发服务器的IP

  • e1.42qu.us
  • 113.11.199.20
_images/dns_set.png

在域名生效前 , dnspod 会提示 “检测到域名没有填写DNS” 的错误 , 不要管它

_images/dns_err.jpg

我们接着走下面的流程 , 域名生效要等上好几个小时 ...

人生充满了等待 ...

如果你的域名不幸被抢注了 , 那就随便注册一个吧 , 下文如何使用自定义域名的方法

登录服务器#

参阅 SSH 登录 Linux服务器 流程说明 , 强烈向windows用户推荐文中提到 xshell ssh客户端

SSH的端口是53002

注意 :

  1. ssh key 已经生成 , ssh-keygen 生成密钥 命令这一句可以跳过
  2. virtualenv 也已经安装

登录后请 执行 passwd 命令 , 修改密码

Fork zpage 项目 到自己的帐号#
_images/fork.png

项目主页

注意 :

  1. fork的那个板块可能被折叠, 导致你看不见fork的链接 , 点击就可以把它展开
  2. 如果bitbucket提示出错, 不管它
添加自己的密钥到bitbucket#

ssh中

cat ~/.ssh/id_rsa.pub

然后 , 复制粘贴 ( https://bitbucket.org/account/ssh-keys/ )

_images/bkssh.png
克隆代码库#

访问 https://bitbucket.org/repo/mine , 点击进入自己的项目

_images/hg_ssh.png

注意 , 不要用privite的项目 , 不然将来没法给官方项目提交自己的修改

找到自己fork的项目ssh的地址 ( 注意不是https的地址 ) , 然后clone

_images/hg_clone.png

请clone到自己home目录下的 zpage 文件夹 (不然会找不到静态文件)

人生充满了等待 ...

加入42qu的官方项目到 hgrc#
_images/hg_rc.png

在 ~/zpage/.hg/hgrc 中加入

42qu = ssh://hg@bitbucket.org/zuroc/zpage

以后就可以通过

hg fetch 42qu

来同步官方代码到自己的fork

配置SMTP邮件服务器#

mailgun.net 注册一个免费的帐号

_images/mailgun.png

找到用户名密码

_images/smtp.png

编辑自己的配置文件

vi ~/zpage/config/user/$USER.py

修改为刚刚注册的SMTP服务器

_images/smtp_config.png

注意 , 因为用户名和密码都写到了配置文件里面 , 而这些是会在开源代码库中公开 , 所以请不要用私人邮箱的SMTP

小贴士 :

Mailgun 是由美国著名的投资者/机构 Y Combinator, SV Angel, Yuri Milner, Maynard Webb, Paul Buchheit (Gmail 创始人之一), Geoff Ralson (Yahoo Mail 创始人) 等投资的一家新兴邮件发送服务提供商。
数据库#

管理的地址 http://e1sql.42qu.us/ , 用户名密码见邮件

注意 : zpage 和 zpage_google 的共用的开发数据库 , 请不要乱动

你可以创建名为 zpage_自己在42qu的个性网址/ID 数据库

启动服务器#

ping 一下开发测试的域名 , 看看ip是否已经指向了ssh服务器的IP

如果没有生效 , 你可以去看场电影

如果成功 , 就可以启动服务器了 , 第一次启动需要压缩css和js , 会稍微慢点

cd ~/zpage
./restart.dev

图片都是挂掉的 , 不管它

要关闭服务 , 请连续按两次 Ctrl + C

登录自己的42区#

为了保护网站用户的隐私 , 开发服务器的数据库对涉及个人隐私的数据都做了替换处理

不过你还是可以用自己帐号登录

首先, 我们要找到自己的邮箱对应的id , 比如访问

http://api.42qu.com/user/info/mail/id?mail=zsp007@gmail.com

其中zsp007@gmail.com为你在42qu.com的注册邮箱

可以看到返回 1 , 那么我们就可以用 1@42qu.com 登录在42qu.com上对应的帐号 (密码不变)

如果登录时提示帐号不存在 , 那就重新注册吧

向官方代码库提交自己的改动#

首先 fetch 线上的代码:

hg fetch 42qu

然后合并完成代码后 , 可以向42qu.com的官方代码库发起pull请求

还是访问 https://bitbucket.org/repo/mine , 点击进入自己的项目

然后, 如图

_images/pull_request.png
域名被抢注了怎么办 ?#

如果你使用邮件里面的默认域名 , 可以无视这一节

首先编辑配置文件

vi ~/zpage/config/user/$USER.py

修改域名那一行为自己的域名

o.SITE_DOMAIN = 'z11e1.tk'

然后重新生成静态文件的引用

cd ~/zpage; rm static/.js_hash static/.css_hash ; python static/make.py

接着参考上文, 向官方代码库提交自己的改动 ; 请只包含配置文件的修改 ;

标题为 : 自定义使用域名 xxx.tk

等管理员确认, 合并, 并重新生成nginx配置文件后 , 就可以使用自己的域名了 :)

遇到问题怎么办 ?#

穿越火线后 , 加入

my42

这个邮件列表 , 然后提问

推荐用Gmail邮箱订阅

提问前 , 请仔细阅读 提问的智慧

管理员备忘#
  1. 开通开发人员的帐号

    1. 登录主机 e1 @ e1.42qu.us

      cd ~/zpage/misc/vps $
      vi vps_new.py  #设置需要开通哪些帐号
      ./vsp_new.sh
      

ZSAE 框架#

项目主页 :

部署到SAE上框架

代码结构和42qu.com (zpage) 相似 , 但是精简很多

开始战斗吧 ...#

准备 bitbucket.org 的帐号#

注册bitbucket帐号,且在本地生成ssh key后,需要将ssh目录中的public key黏贴至下图所示位置。

添加ssh key

#TODO

克隆代码库#

在自己的 ~/ 目录下 创建 .hgrc , 内容如下, 并修改 username 为自己的个人信息

.hgrc

[ui]
username = XXX <xxx@gmail.com>
verbose = True
ssh = ssh -i ~/.ssh/id_rsa -C
ignore = ~/.hgignore

[extensions]
hgext.purge=
color=
hgext.fetch=
bookmarks =
hggit =

[color]
status.modified = blue underline red_background
status.added = green
status.removed = red blue_background
status.deleted = cyan underline
status.unknown = magenta underline
status.ignored = black

diff.diffline =
diff.extended = cyan
diff.file_a = red
diff.file_b = green
diff.hunk = magenta
diff.deleted = red
diff.inserted = green
diff.changed = white
diff.trailingwhitespace = red_background

[alias]
blame = annotate --user --number

在自己的 ~/ 目录下 创建 .hgignore , 内容如下 ; .hgignore 用来注明不需要进行版本控制的文件

.hgignore

syntax: glob
*.elc
*.pyc
*~
*.swp
*.bak
.svn
supervise
nohup.out

*.htm.py
*.txt.py
local_config.py
my_local_config.py
__init_file_hash__.py
.*.js
.*.css
.css_hash
.js_hash

然后 , 克隆代码库

hg clone ssh://hg@bitbucket.org/zuroc/zpage
配置域名解析#

网络的设置参见 http://doc.42qu.me/vmware.html

以下以 huhuchen 用户作为演示 , 大家请用自己相应的用户名

打开 /etc/dnsmasq.conf

加入

address=/huhuchen.xxx/192.168.1.103

重启 dnsmasq

sudo /etc/init.d/dnsmasq restart

访问 http://huhuchen.xxx/ 可以看到 nginx 404 的页面提示

#TODO dnsmasq 是什么?

配置 nginx#

编辑 ~/zpage/config/nginx.py , 在这里加上自己的用户名

render_machine('krios', """
huhuchen
zuroc
wooparadog
work
realfex
""")

~/zpage/config/user 目录下

cp zuroc.py huhuchen.py
hg add huhuchen.py

修改其中域名和端口为自己的

运行脚本, 重新生成nginx配置文件

zuroc@krios ~/zpage/config $ python nginx.py

这里可以看到新生成的nginx配置文件

zuroc@krios ~/zpage/config $ vi nginx/krios/huhuchen.conf

重启 nginx 服务器

sudo /etc/init.d/nginx restart

注意 , 可能需要修改 /etc/nginx/nginx.conf 里面以下两行为自己的目录

include /home/zuroc/zpage/config/nginx/zpage.conf;
include /home/zuroc/zpage/config/nginx/krios/*.conf;
运行 42qu.com zpage框架#

首先编译静态文件

huhuchen@krios ~/zpage $ python static/make.py

然后启动开发服务器

huhuchen@krios ~/zpage $ ./server_ctrl_dev.py

访问 http://huhuchen.xxx 就可以看到42qu.com了 :)

创建自己的分支#

首先新建自己分支

hg fetch
hg branch huhuchen_20091012_my_first
hg commit -m"fix"
hg push

分支的命名规则 : 用户名_日期_功能描述

hg的用法 http://doc.42qu.me/HgUsge.html

进入开发流程#

http://doc.42qu.me/step.html

代码开发流程#

  1. 产品设计
    1. 明确要做的事情
      1. 列出所有想法, 以及对应的原型, 我们可能的去做的形态
      2. 分析与网站定位的关系, 如何去运营
    2. 细化为功能点
      1. 找到所有的同类产品 , 并试用, 列出他们的功能点
      2. 对照这些产品, 列出我们需要的功能点
      3. 安排档期, 一期工程要做哪些, 二期工程要做哪些
      4. 给每个功能点安排开发的先后次序
    3. 设计URL
      1. 能直接访问的页面
      2. 每个页面的后续页面
    4. 编写文案

  2. 后端开发
    1. 创建分支 分支的命名规则为 zuroc_20110103_rss ( 开发者_日期_功能名 )

      #. 如果是开源的志愿者, 请先fork一份代码, 然后创建按照以上规则分支

    2. 数据库
      1. 设计前请先阅读 表设计指南
      2. 明确用到的表以及相应结构
      3. 明确索引字段
      4. 运行 zpage/misc/backup/backup_table.sh 备份表结构并push到版本控制
    3. 设计函数接口
      1. 函数命名参见 PEP8
        1. 缩近, 参数位置, =符号等等. 安装 zpage/linux/config.d/pythius 后可用 pydent . 排版当前目录下的所有python文件
        2. 参考 vim 配置文件 ~/zpage/linux/conf.d/vimrc , 可以把 F12 映射为 排版当前文件 , F11映射为运行当前python文件
    4. 创建分支

    5. 开发后台代码

    6. 向前端介绍任务(在workflow.com上创建以下标签, 并写清楚说明)
      • 使用场景 + 网址

        # 注意点

      • 设计原型

      • 后台接口

      • 分支名称

  3. 前端开发
    1. 设计原型页
    2. 整理页面CSS代码
    3. 编写页面的Javascript代码
    4. 整合后台代码与页面
  4. 质量保证
    1. 自行页面测试
    2. code review
    3. 修改 再 code review 直到没修改
    4. 其他人页面测试
  5. 最终上线
    1. 合并上线
    2. 更新待做事项的文档

42qu.com 代码实战篇#

首先 , 每天开始写代码前先hg fetch一下代码 , 更新到最新版本 ;

这是个好习惯, 可以避免很多不必要的代码冲突 ;

另外, fork的分支 , 需要先 fetch 42qu (参考SSH开发帐号开通邮件的教程), 可能才能看到以下的教程中的分支和改动

然后我们开始一个新模块前会新建一个新的分支

hg branch zuroc_20120518_vps_ip

注意这里的分支命名规则

自己常用英文名字_日期_分支名称

分支创建完成后建议先commit一次 , 方便将来查看这个分支的修改diff

z32@e1 ~/zpage $ hg commit -m"fix"
committed changeset 14277:8367ebf5b632

在 $HOME/.hgrc 中的[alias]小结下添加这一行

bdiff = diff -r "max(ancestors('$1') and branch(default)):'$1'"

然后可以通过:

hg bdiff zuroc_20120518_vps_ip

来方便查看这个分支的改动了 :)

实战案例#
后端#
VPS 管理页面 可以按 机房 浏览 IP#

作者 : 张沈鹏

网址 : http://god.42qu.com/vps/room/ip

分支 : zuroc_20120518_vps_ip

代码 :

z32@e1 ~/zpage $ hg bdiff zuroc_20120518_vps_ip | pastebin

http://dpaste.de/Ya2hy/raw/

备注 :

线上后台有密码

请用自己的开发服务器的看

work@potato ~/zpage $ ./restart.god

同时请修改 ~/zpage/config/default.py 中的 o.PRIVILEGE_SUPER

加入自己的在开发服务器上的数字ID , 以获取管理员的权限

页面 :

_images/1.png _images/2.png
图表统计 thrift 接口 & 数据保存#

作者 : 张沈鹏

演示 :

线上服务器 , 执行如下命令

work@potato ~/vps $ python server/model/plot.py

输出如下

print plot_point(PLOT_CID_VPS_NETFLOW_1MIN_HOST, 3, 1440, 1024*1024/8)
[11L, 10L, 8L, 12L, 11L, 10L, 11L, 10L, 11L, 8L, 10L, 8L, 9L, 13L, 13L, 10L, 12L, 10L, 13L, 7L, 8L, 7L, 9L, 8L, 8L, 10L, 6L, 6L, 9L, 12L, 9L, 8L, 7L, 7L, 12L, 10L, 8L, 12L, 11L, 13L, 12L, 9L, 9L, 11L, 12L, 9L, 9L, 10L, 12L, 14L, 8L, 8L, 11L, 14L, 9L, 9L, 9L, 13L, 14L, 11L, 15L, 11L, 14L, 10L, 13L, 11L, 11L, 15L, 7L, 7L, 14L, 10L, 10L, 15L, 11L, 18L, 12L, 14L, 12L, 11L, 10L, 11L, 16L, 9L, 10L, 10L, 11L, 9L, 12L, 13L, 15L, 14L, 13L, 10L, 10L, 10L, 12L, 10L, 11L, 9L, 9L, 11L, 9L, 12L, 14L, 15L, 14L, 20L, 14L, 16L, 14L, 12L, 13L, 16L, 12L, 15L, 12L, 16L, 18L, 13L, 16L, 15L, 15L, 12L, 15L, 20L, 13L, 18L, 18L, 9L, 11L, 13L, 11L, 11L, 8L, 8L, 6L, 8L, 12L, 12L, 11L, 10L, 10L, 10L, 10L, 11L, 8L, 11L, 11L, 8L, 7L, 10L, 11L, 13L, 9L, 6L, 7L, 7L, 8L, 8L, 10L, 10L, 9L, 5L, 7L, 10L, 5L, 8L, 9L, 7L, 7L, 9L, 7L, 9L, 8L, 9L, 8L, 10L, 7L, 8L, 11L, 8L, 11L, 11L, 11L, 7L, 10L, 7L, 6L, 7L, 7L, 6L, 4L, 9L, 7L, 9L, 11L, 6L, 8L, 8L, 6L, 9L, 9L, 10L, 9L, 7L, 9L, 8L, 9L, 12L]

plot_point(PLOT_CID_VPS_NETFLOW_1MIN_HOST, 2, 1440, 1024*1024/8)
[0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 1L, 1L, 1L, 1L]

print plot_point(PLOT_CID_VPS_NETFLOW_1MIN, 95, 1440, 1024*1024/8)
[8L, 6L, 5L, 8L, 8L, 7L, 7L, 7L, 7L, 4L, 6L, 5L, 6L, 9L, 9L, 7L, 7L, 8L, 10L, 5L, 6L, 5L, 5L, 5L, 5L, 7L, 4L, 4L, 6L, 8L, 6L, 6L, 5L, 6L, 9L, 8L, 7L, 9L, 8L, 9L, 6L, 7L, 8L, 9L, 9L, 6L, 7L, 7L, 9L, 8L, 7L, 7L, 7L, 12L, 6L, 8L, 7L, 10L, 9L, 9L, 12L, 8L, 8L, 8L, 8L, 8L, 7L, 8L, 5L, 5L, 11L, 8L, 8L, 11L, 8L, 10L, 8L, 10L, 10L, 8L, 7L, 8L, 11L, 7L, 8L, 7L, 6L, 7L, 8L, 7L, 8L, 11L, 10L, 8L, 7L, 9L, 10L, 7L, 8L, 7L, 8L, 10L, 9L, 11L, 11L, 9L, 7L, 9L, 8L, 8L, 8L, 8L, 10L, 13L, 10L, 12L, 8L, 8L, 11L, 8L, 6L, 9L, 9L, 8L, 11L, 12L, 7L, 10L, 12L, 8L, 10L, 12L, 10L, 10L, 8L, 8L, 6L, 7L, 12L, 11L, 10L, 9L, 9L, 9L, 10L, 11L, 8L, 10L, 11L, 7L, 6L, 10L, 11L, 11L, 8L, 5L, 6L, 6L, 8L, 7L, 9L, 9L, 8L, 4L, 6L, 9L, 4L, 7L, 9L, 6L, 7L, 9L, 6L, 8L, 8L, 8L, 7L, 10L, 7L, 7L, 10L, 8L, 10L, 10L, 10L, 6L, 9L, 7L, 6L, 6L, 6L, 6L, 4L, 7L, 6L, 9L, 10L, 5L, 7L, 7L, 6L, 8L, 9L, 9L, 8L, 6L, 8L, 8L, 8L, 11L]

print plot_point(PLOT_CID_VPS_NETFLOW_1MIN, 14, 1440, 1024*1024/8)
[2L, 2L, 3L, 3L, 3L, 2L, 3L, 2L, 3L, 3L, 3L, 2L, 2L, 3L, 3L, 2L, 4L, 1L, 3L, 1L, 2L, 2L, 3L, 2L, 3L, 2L, 1L, 1L, 1L, 3L, 2L, 2L, 1L, 1L, 2L, 1L, 0L, 2L, 3L, 3L, 5L, 1L, 0L, 1L, 2L, 2L, 2L, 2L, 2L, 5L, 1L, 0L, 4L, 2L, 2L, 0L, 1L, 2L, 5L, 2L, 3L, 2L, 5L, 1L, 4L, 3L, 4L, 6L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 8L, 3L, 3L, 1L, 2L, 2L, 3L, 4L, 2L, 1L, 2L, 4L, 2L, 3L, 6L, 7L, 3L, 2L, 1L, 2L, 0L, 1L, 2L, 2L, 2L, 1L, 1L, 0L, 0L, 2L, 6L, 6L, 10L, 5L, 8L, 5L, 3L, 2L, 3L, 1L, 2L, 3L, 7L, 7L, 5L, 8L, 5L, 5L, 3L, 3L, 7L, 5L, 7L, 6L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L]

其中 plot_point 函数定义如下

plot_point(cid, rid, limit, base=None):

参数含义如下 :

cid 是 category id 的缩写 , 代表 类型

rid 是 relative id 的缩写 , 代表 相关id

limit 的 限制 取多少条

base 表示基数 , 比如 bytes 要换算成 Mbps , 那么 base 设置为 1024*1024/8

备注 :

这是一个图表基础设施开发的第一步

提供api , 可以方便的创建一个图表 , 类似短网址, 可以方便的

  1. 保存统计数据
  2. 展示统计数据

其中 thrift 是 facebook 开源的一个rpc框架

saas/ 目录下的python文件改动 是 修改 saas.thrift 后, thrift框架自动生成的代码 , 你可以忽略他们

仓库 :

代码 :

git diff 8032c5d5468a608b8219b2d1051291bf017eca72|pastebin

http://dpaste.de/7mXMy/raw/

VPS 添加带宽计费模式#

作者 : 张沈鹏

表结构 :

vps_type 和 vps_one 分别添加字段

bandwidth int(10) UNSIGNED

前端#
给 vps 管理页面右侧添加 返现链 模块 ( lnav )#

作者 : 张沈鹏

演示 :

代码 :

hg bdiff zuroc_20120521_vps_reward|pastebin

http://dpaste.de/rqHUg/raw/

新人加入流程#

向管理员申请开通 http://42qutk.sinaapp.com/project-task-1.html 上的项目权限

登录后请 修改密码 并 补充个人的联系方式 (手机, QQ, Gtalk 等)

有任何产品上的想法 请在相应的产品下提交

SAAS ( Software-as-a-service )#

以下文档为 Google Docs , 需要翻墙访问

创建服务 , 请在这里登记 (需向负责人申请编辑权限)

查找服务 , 可以访问这里

42qu.com 笔试题#

以下为非常不完整的42qu.com待处理事项说明;

你可以选择你感兴趣的事项的笔试题来回答 ;

创业公司, 特别欢迎能同时胜任多个角色的多面手 ;

简历请用纯文本邮件(设计类除外) , 对照下面的事项 :

  1. 条理清晰地枚举出您的觉得您可以胜任的任务 , 分别用一小段文字描述你为什么觉得可以胜任
  2. 回答笔试题

投递邮箱 : 42qu.hr@gmail.com

欢迎您的来信 ;

技术实习#
后端#

基本要求 :

  1. 能熟练使用vim 和 linux基本命令
  2. 会用 python 进行开发

笔试题目 :

  1. fork 下面这个代码库 ( 注: fork流程参见 这里 )

    http://book.42qu.com/42qu/sae.html

    并在此基础上, 在SAE上实现 监控 新浪微博微话题 的 所有频道的每日更新

    并将更新汇总为一份邮件 , 定期发送到制定邮箱

前端#

基本要求:

  1. 熟悉Jquery

笔试题目:

请参考网站现有风格和元素 , 设计42区手机版的个人主页 (如果会HTML , 欢迎用HTML来实现)
非技术#

基本能力要求

  1. 文档能力 : 能将常见问题整理成为文 , 并归纳总结日常工作流程
  2. 进展汇报 : 定期向我邮件回报 当前的进展(自行制定数据化的指标) 和 遇到的问题 , 每周给出本周小结
  3. 善于发现 : 可以进一步开展工作 , 现有不合理的地方 , 并及时反馈
  4. 对我们的产品要有爱
与人联系#

事项举例 :

  1. 文化衫业务(即将开展) , 需要与一些初创公司去联系并洽谈合作
  2. 主机业务 , 会有常常有些咨询 , 需要回复 , 这需要些技术方面基础知识
  3. 与一些互联网上活跃并符合网站气质的人联系, 邀请他们入驻
  4. 去参加各种线下的聚会 , 宣传我们的业务

能力要求 :

  1. 待人诚恳亲情 , 有感染力
  2. 做事有条理 , 能分清楚步骤, 并草拟计划

笔试题目 :

  1. 你会从哪儿去整理创业公司/现有社区
  2. 如果你是BOSS , 你觉得应该分别怎样为 创业公司/现有社区 以 提供印制文化衫 来开始其与42区的合作 (我们帮他们解决哪些他们会觉得麻烦问题) 请简述 1, 2 , 3, 4, 5 ...
  3. 在第二个问题的基础上, 写一份联系邮件, 作为与他们洽谈合作的开始
站内运营#

负责事项 :

  1. 在管理后台选择并转发优秀文章或内容
  2. 删除不符合网站要求用户头像/资料
  3. 编写文案 , 对站内站外用户介绍网站的新功能
  4. 写邮件周报 , 精选近期网站上的优质内容
  5. 与用户沟通, 并告诉他网站的价值观 , 引导其产生有用的信息

笔试题目 :

  1. 写一篇介绍42区短文案 ; 参考豆瓣的介绍 http://www.douban.com/about

Python 文化衫#

关于Python#

Python是一门跨平台的脚本语言,Python支持几乎所有常用的操作系 ;

Google.com (python创始人在此工作) , Douban.com(全球最大的基于python的网站) 以及 42qu.com (我的项目 :) 都是python的忠实用户 ;

Python 让编程变得简单 。

关于python更多信息, 见 http://python.orghttp://python.cn

python在工业领域也有很多应用, 比如:

我们(42qu.com)将在稍后发起一个基于python的无人驾驶汽车项目

欢迎加入此项目的google groups : http://groups.google.com/group/42qu-tardis?hl=zh-cn

本次北京python用户聚会 , 我们将分享关于此无人驾驶汽车项目的主题

欢迎围观 , 报名链接 : http://zuroc.42qu.com/10312744

设计投票#

图案的网址 :

以及 图4 & 图5

图1 以 文化衫购买页面的为准 :

投票选项 :

  1. 图正面是否要有大的文化衫图案 (我倾向于有大图案, 1.jpg)

    1. 如果用大图案 , 你有什么设计细节的调整建议

    2. 如果没有大的图案, 可以用绣花绣上python的文字和小logo

      http://www.my51.com/buy/images/t/009.jpg

  2. 袖口是否要有如图中的臂章
    1. 如果有臂章是用 纯色 (2.jpg) 还是用 黄色+蓝色 (3.jpg)
  3. 背面的python logo 是放在python文案的前面 (1.jpg) 还是 替代python的 o( 2.jpg )

制作工艺#

本次文化衫底衫材料将会采用 美国长绒皮马棉文化衫 ( pima棉 )

PS : 上次自己印刷了一款文化衫, 材料不好 ; 所以这次就打算用最好的材料来做

面料说明 :

Pima棉是极品特长绒棉(ELS)的统称,美国部分地区(主要是西部和西南部)、秘鲁、埃及、以色列、澳洲和中国现在都有pima棉出产。Pima棉以前被称为American Egyptian Cotton,现在是根据美国西南部Pima印第安种植和用手采摘棉花的传统而命名。日本是全球进口最多的国家。

在全球棉花生产中,只有3%可以被称为ELS(特长绒棉)或极品棉。现有的优质棉主要分为四类:埃及棉、秘鲁pima棉、美国pima棉和海岛棉。虽然四种棉花分别在四个地方种植,但品质都不相伯仲。

面料更多介绍见 <闲聊PIMA棉> : http://patagoniac.blogbus.com/logs/45071728.html

印刷工艺 :

丝网胶印,文化衫印花最常用的工艺,不受面料底色影响。

印花胶浆环保不含甲醛,采用的环保胶浆,可以使用在儿童内衣的印花上,可贴身穿着。

印出花型手感柔软、舒适,有光泽,色牢度强,可以机洗。

订购方式#

为了避免不必要的库存浪费 , 我们采用先预定后生产的方式 , 订购链接如下:

将于6月底 , 交付工厂制作并发货 ;

将按照预定数生产 , 不留存货 ; 错过这次 , 就要等到明年夏天了 ...

每件 89 元 , 开支说明如下

费用说明#

细节如下 :

  • 10% 用于成立一个python的基金 , 此基金将用于奖励python中文圈优秀的博客作者和文章译者

    文章将每月由大家投票选出 , 稍后我会给出进一步的规则细节(需要写一些代码)

  • 10% 分给本文化衫的设计师

    • 王真真 //文化衫整体设计
    • Riku Lu //提供 pycon china 2011 的 Logo 图案

    备注 :

    我们的下一款文化衫主题是 : 我是单身程序员 或者 我单身 无所谓

    欢迎各位设计师提交自己关于各种主题的文化衫设计方案

    请邮件到 42qu.shirt@gmail.com , 我们会给设计师计费用提成

  • 您可以在自己博客/网站上 挂上此文化衫的购买链接 ; 将分得导购收入10%的提成

    生成链接网址如下 , 登录后可见 :

  • Pima棉底料 + 印刷 , 成本 55 元 (成本根据定做数浮动, 这是50件的价格)

特别优惠#
  • 购买42qu VPS 中国区的 1G以上内存一次性年付 的用户

    将免费获赠一款python文化衫 ( 2012 . 6 . 12 - 28日 有效 )

    入口链接 : http://vps.42qu.com/by/zuroc

    7线BGP机房 512M内存 月付仅99元 , 网站可以边备案 边上线 ;

  • 关于我们VPS的故事 :

  • 本次北京python用户聚会上分享以下主题 , 我将分享以下主题 :

    42区 : 基于 Thrift + python , 编写 VPS 管理系统

    欢迎大家报名参加 , 报名链接 :

最后的话#

欢迎在您微博上 推荐 本文 的 链接

也可以用提成链 , 生成链接网址如下 , 登录后可见 :

人生苦短 , 我用python ^o^

Python 网站开发 . 2012 暑期零基础入门班#

课程共 16 天 , 周一到周五, 限 15 人 , 费用约 2500 元

报名详情见 : http://zuroc.42qu.com/10316417

咨询邮箱 : 42qu.py@gmail.com

最终我们会做出一个类似 点点 , 新浪轻博客 , 人人小站 , 网易 Lofter , Tumblr 的轻博客网站

每节课都会有课后作业 , 并有专人负责答疑

成绩优秀的学员我们将会向各大 IT 公司推荐实习

教学大纲草案如下 , 完善中 ...

01. Hello, world!#
  1. 在 GoDaddy 购买域名
  2. 设置域名解析服务器为 DNSPod
  3. 使用 DNSPod 将已购域名定向到 VPS 开发机
  4. Linux 入门
  5. Vim 的简单使用
  6. 在开发机上安装配置 Nginx
  7. 创建 Hello World 页面并部署
注意事项#
  1. 如果想上课的时候购买域名 , 请给支付宝帐号上预留70元 , 并想好要注册的域名
02. 注册、登陆页面#
  1. Firefox 开发插件介绍
  2. 注册、登陆页面
  3. 页面切换效果
03. Web 框架#
  1. Python 基本语法
  2. Python 常用数据结构和模块
  3. 使用 supervisor 部署开发服务器
  4. Nginx 分离静态和动态文件
  5. Nginx 代理到 Tornado
  6. 使用模版系统重写 Hello World
04. 版本控制和数据库#
  1. Mecurial 使用
  2. 配置 MySQL
  3. 配置本地工具连接 MySQL
  4. 创建用户表结构
  5. 用 tornado.database 连接 MySQL 并写入数据
05. Redis#
  1. 邮箱重复注册提示
  2. 使用正则表达式校验邮箱格式
  3. 配置 mailgun 发送激活邮件
  4. 使用 redis 的 BLPOP 把发送激活邮件改成异步的
06. 更多页面#
  1. 博客新建页面、个人首页和全站首页的设计
  2. 每个博客绑定二级域名
  3. 个人资料填写页面
  4. 修改邮箱,修改密码
  5. 博客设置页面
07. 文章发布#
  1. 文章新建页面
  2. 设计博客文章表结构
  3. 文章发布的后台开发
08. 标签系统#
  1. 给文章加标签
  2. 同一标签文章展示
  3. 标签一览表
  4. 为博客选择分类
  5. 同一分类博客展示
  6. 分类一览表
09. 图片系统#
  1. 博客头像上传
  2. 博客头像出现在个人页面和首页时间线中
  3. 用户头像上传
  4. 头像缩略图调整
10. 更多格式#
  1. 发布图片格式的文章
  2. 发布声音
  3. 发布视频
  4. 发布链接
11. 评论系统#
  1. 给文章添加评论
  2. 评论频率太快需要输入验证码
12. RSS#
  1. 插入百度统计功能
  2. 创建博客的 RSS 输出
13. 同步#
  1. 博客可以绑定 RSS 源
  2. 转换非全文输出 RSS 为全文输出
14. 爬虫#
  1. 编写爬虫 , 为没有 RSS 的网站创建 RSS 源
  2. 使用crontab定期抓取
15. 发布到其他平台#
  1. 微博登录
  2. 同步文章到微博
16. 关注与消息流#
  1. 关注系统的实现
  2. 消息流的合并

reStructuredText简明教程#

作者:刘斗 redfork@gmail.com
Changelog:
  • 120228 Zoom.Quiet appended skills

段落#

REST 是松散的文本结构,使用预定义的模式描述文章的结构。首先学习最基本的结构:段落。

段落是被空行分割的文字片段,左侧必须对齐(没有空格,或者有相同多的空格)。

缩进的段落被视为引文。

继续缩进……

恢复

恢复

文字样式#

最简单的样式是 斜体粗体.

  • *斜体*. 被*包围的文字是斜体
  • **粗体**. 被**包围的文字是粗体

注意: * 两侧必须留有空格, 英文标点符号. 输入法设置为英文标点, 并使用正确的英文标点规范 (逗号, 句号后留一个空格, 引号, 括号两侧留一个空格).

列表#

有三种列表:

  1. 顺序,
  2. 公告牌,
  3. 定义.

列表前后, 以及条目之间必须有空行隔开. 列表下面可以插入任意的内容, 段落, 图片都可以, 只要他们的左侧和列表的第一个文字左对齐.

顺序列表#
1. 第 **一** 条

   段落

#. 第二条

   1. 小条

#. 第三条

顺序列表 生成:

  1. 段落

  2. 第二条

    1. 小条
  3. 第三条

第二条开始后续的条目用 # 开头

顺序列表 - 序号#

第一条的序号不必从 1 开始:

3. 第三条

#. 第四条

7. 重新设定序号

#. 继续

顺序列表 - 序号 生成:

  1. 第三条
  2. 第四条
  1. 重新设定序号
  2. 继续
顺序列表 - 符号样式#

符号:

1. 数字

a. 小写字母

A. 大写字母

i) 小写罗马数字

(I) 大写罗马数字

顺序列表 - 符号样式 效果

符号:

  1. 数字
  1. 小写字母
  1. 大写字母
  1. 小写罗马数字
  1. 大写罗马数字
公告牌列表#

和顺序列表相似, 使用 “*” “+” “-” 代替数字:

* 列表第一级

  + 第二级

    - 第三级

  + 第二级的另一个项目

公告牌列表 生成:

  • 列表第一级
    • 第二级
      • 第三级
    • 第二级的另一个项目

定义列表#

或者叫名词解释更确切:

*鸡*
  两条腿, 直立行走, 带翅膀, 有头冠的动物.

*鸭*
  鸡的崇拜者

定义列表生成:

两条腿, 直立行走, 带翅膀, 有头冠的动物.
鸡的崇拜者

嵌入程序代码#

如果需要嵌入大段的程序代码(SQL, 业务逻辑设置, 配置文件等), 在段落末尾添加两个’:’. 代码的左侧必须缩进, 代码引用到没有缩进的行为止. 例如:

如果数据库有问题, 执行下面的 SQL::

 # Dumping data for table `item_table`

 INSERT INTO item_table VALUES (
   0000000001, 0, 'Manual', '', '0.18.0',
   'This is the manual for Mantis version 0.18.0.\r\n\r\nThe Mantis manual is modeled after the [url=http://www.php.net/manual/en/]PHP Manual[/url]. It is authored via the \\"manual\\" module in Mantis CVS.  You can always view/download the latest version of this manual from [url=http://mantisbt.sourceforge.net/manual/]here[/url].',
   '', 1, 1, 20030811192655);

嵌入程序代码生成:

如果数据库有问题, 执行下面的 SQL:

# Dumping data for table `item_table`
INSERT INTO item_table VALUES (
  0000000001, 0, 'Manual', '', '0.18.0',
  'This is the manual for Mantis version 0.18.0.\r\n\r\nThe Mantis manual is modeled after the [url=http://www.php.net/manual/en/]PHP Manual[/url]. It is authored via the \\"manual\\" module in Mantis CVS.  You can always view/download the latest version of this manual from [url=http://mantisbt.sourceforge.net/manual/]here[/url].',
  '', 1, 1, 20030811192655);
嵌入程序代码 续#

如果没有合适的段落添加 ::, 也可以在一个空行上添加, 这个双冒号行被忽略:

::

#
# Dumping data for table `item_table`
#

INSERT INTO item_table VALUES (
  0000000001, 0, 'Manual', '', '0.18.0',
  'This is the manual for Mantis version 0.18.0.\r\n\r\nThe Mantis manual is modeled after the [url=http://www.php.net/manual/en/]PHP Manual[/url]. It is authored via the \\"manual\\" module in Mantis CVS.  You can always view/download the latest version of this manual from [url=http://mantisbt.sourceforge.net/manual/]here[/url].',
  '', 1, 1, 20030811192655);

嵌入程序代码 续 生成:

#
# Dumping data for table `item_table`
#

INSERT INTO item_table VALUES (
  0000000001, 0, 'Manual', '', '0.18.0',
  'This is the manual for Mantis version 0.18.0.\r\n\r\nThe Mantis manual is modeled after the [url=http://www.php.net/manual/en/]PHP Manual[/url]. It is authored via the \\"manual\\" module in Mantis CVS.  You can always view/download the latest version of this manual from [url=http://mantisbt.sourceforge.net/manual/]here[/url].',
  '', 1, 1, 20030811192655);
程序引用体例#

可以 用 .. code-block:: 追加各种语法高亮声明:

.. code-block:: python
    :linenos:

    def foo():
        print "Love Python, Love FreeDome"
        print "E文标点,.0123456789,中文标点,. "

效果:

1
2
3
def foo():
    print "Love Python, Love FreeDome"
    print "E文标点,.0123456789,中文标点,. "

外部包含:

.. literalinclude:: example.py
    :language: python

效果:

@route('%s/'%ini.urlprefix)
def index():
    __urlog("INFO","idx++")
    return template('index.tpl',urlprefix=ini.urlprefix)

章节#

章节是文章的主体结构, 分为 标题 章 节 小节 等. 定义章节的方式是在行的下面添加 ‘=======’, 比如:

标题
====

章
--

节
~~

小节
####

说明 [1]:

  1. ‘====’ 至少和文字行一样长, 更长也行
  2. 相同级别必须使用统一的符号, 否则会被识别为更小的级别
  3. = - ~ ` : ‘ ” ^ _ * _ # < > 这些符号都可以, 级别足够多了.
[1]由于幻灯片系统的限制, 效果无法在幻灯片内演示

标题#

标题和章节在结构上的作用相同, 但是可能有不同的显示格式. 标题的区别是在章节的上方也加上 ‘====’ 行:

====
标题
====

-----------
第一章 概述
-----------

表格#

普通表格#
+------------+------------+-----------+
| Header 1   | Header 2   | Header 3  |
+============+============+===========+
| body row 1 | column 2   | column 3  |
+------------+------------+-----------+
| body row 2 | Cells may span columns.|
+------------+------------+-----------+
| body row 3 | Cells may  | - Cells   |
+------------+ span rows. | - contain |
| body row 4 |            | - blocks. |
+------------+------------+-----------+

普通表格 生成:

Header 1 Header 2 Header 3
body row 1 column 2 column 3
body row 2 Cells may span columns.
body row 3 Cells may span rows.
  • Cells
  • contain
  • blocks.
body row 4
简单表格#

注意: 表格包含中文时,基本无法对齐,,,

=====  =====  ======
   Inputs     Output
------------  ------
  A      B    A or B
=====  =====  ======
False  False  False
True   False  True
False  True   True
True   True   True
=====  =====  ======

简单表格 生成:

Inputs Output
A B A or B
False False False
True False True
False True True
True True True
CSV 表格#
.. csv-table:: Frozen Delights!
 :header: "Treat", "Quantity", "Description"
 :widths: 15, 10, 30

 "Albatross", 2.99, "On a stick!"
 "Crunchy Frog", 1.49, "If we took the bones out, it wouldn't be
 crunchy, now would it?"
 "Gannet Ripple", 1.99, "On a stick!"

CSV 表格生成:

Frozen Delights!
Treat Quantity Description
Albatross 2.99 On a stick!
Crunchy Frog 1.49 If we took the bones out, it wouldn’t be crunchy, now would it?
Gannet Ripple 1.99 On a stick!
列表表格#
.. list-table:: Frozen Delights!
  :widths: 15 10 30
  :header-rows: 1

  * - Treat
    - Quantity
    - Description
  * - Albatross
    - 2.99
    - On a stick!
  * - Crunchy Frog
    - 1.49
    - If we took the bones out, it wouldn't be
      crunchy, now would it?
  * - Gannet Ripple
    - 1.99
    - On a stick!

列表表格 生成:

Frozen Delights!
Treat Quantity Description
Albatross 2.99 On a stick!
Crunchy Frog 1.49 If we took the bones out, it wouldn’t be crunchy, now would it?
Gannet Ripple 1.99 On a stick!

rST排版技巧#

跨章节指引#
  • 行文中,经常要对其它章节进行指引,在 html 中对应的就是 锚点链接

  • rST 中提供了非常优雅的解决:
    • 使用通用元素定义
    • 比如説:
各个章节的首页一般是 index.rst
头一行,习惯性加个聲明:
.. _chapter6index:

那么,在其它任意文本中,随时可以使用:
:ref:`构建 buzz <chapter6index>`
来生成一个指向第二章 首页的链接!
插图/表格指代#
  • 行文中,经常对指定插图/表格 进行指代

  • rST 中提供了非常优雅的解决:
    • 进行通用元素定义
    • 比如说
.. _fig_0601:
.. figure:: _static/figs/magic-2.png

   插图 6-1 神奇的2

然后,就可以在任意地方使用 插图 6-1 神奇的2 来指代, 实际输出的就是 “插图 6-1 神奇的2”

_images/magic-2.png

插图 6-1 神奇的2

上下标号#

有时要进行数学/化学的表示,在 html 中就需要上/下标( <sub> , <sup>) 的表达, rST 中当然也有:

H\ :sub:`2`\ O
E = mc\ :sup:`2`

效果:

H2O

E = mc2

Note

注意:

这里的 只是为了制造语法空间,输出时,是没有空格的了,,,

段落层次约定#

使用 reSTsections

共分4级
=======================
大标题
=======================


-----------------------
小标题
-----------------------


^^^^^^^^^^^^^^^^^^^^^^^
二级标题
^^^^^^^^^^^^^^^^^^^^^^^


"""""""""""""""""""""""
三级标题
"""""""""""""""""""""""

再小,就使用列表!:

  • 列表项目1
  • 列表项目2
  • ...

42qu VPS#

我们的客户咨询邮箱 42qu-vps@googlegroups.com

备案FAQ#

  • 购买国内vps,备案期间用不了,这个费用怎么算?

    您可以先开通vps正常使用,在不关站的情况下申请备案。

  • 如何对网站进行备案?

    42qu中国区vps只欢迎正规合法网站,违规网站一律封禁。

    备案有两种方式:

    1. 自行备案
    2. 42qu代您备案
  • 自行备案如何操作?

    自行备案,客户需要准备相关材料并前往机房拍照。

    42qu中国区vps的物理服务器分布于北京市的多个机房。

    请根据您购买vps时选用的机房,按照以下说明进行自行备案:

    • 东直门机房

      登录机房备案网站 http://220.231.20.227 ,新用户请先注册后登录。

      首次报备请选择新增备案录入选项卡,填写备案主体信息和新增网站信息; 如果您已有备案主体资格(以前备过案),请选择新增网站录入选项卡, 填写新增网站信息。

      所需材料:

      1. 核验单打印2份,打印出来的效果应是: 第一页的表格显示在完整的一页纸上,不能分页或显示不全; 最下面是网站负责人签字,年月日,旁边盖公章。 核验单需要原件,修改复印无效。内容不须填写,现场核验后由机房选填。

        核验单点此下载

      2. 证件的清晰版复印件(以便扫描后上传给管局系统),如下:

        企业:营业执照副本复印件

        事业单位:组织机构代码证复印件

        个人:身份证原件

        以及网站负责人身份证复印件,网站IP地址的相关信息。

      全部资料准备好后,请网站负责人到机房进行现场面审。

      办公地址:东城区东直门东环广场A座地下一层光环新网机房

      办公时间:上午8:30-12:00,下午12:00-17:00

      电话:010-64182200-2

    • 石景山机房

      公司备案所需材料:

      1. 公司营业执照副本复印件3份
      2. 网站负责人身份证复印件3份
      3. 网站负责人身份证原件
      4. 公司公章

      个人备案只需要带身份证原件和复印件就可以了。

      自行备案需要到机房去拍照,去备案前请先发邮件 42qu-vps@googlegroups.com 联系。

      机房另外收取50元备案手续费用。

      地址:北京市石景山区石景山路23号中础大厦2层220

      电话:010-68832184

  • 如何由42qu代为备案?

    请确保您的网站不属于敏感类型,不涉及违规内容。

    您只需提供网站域名、负责人姓名和联系方式、网站IP, 发送邮件到 42qu-vps@googlegroups.com ,我们会对您的请求进行确认,如果符合要求我们将代您备案。

    此方式获取的备案号将挂在42qu公司的备案主体下。

    由于很多客户希望由42qu代备案,再加上冗长的备案手续和周期, 此方式获取备案的周期往往非常长。

    推荐用户自行前往机房备案。

  • 之前在其它空间商已备过案的,可以免备案吗?

    理论上来说是不行的,您需要:

    • 如果您自行备案,请前往机房拍照并申请变更原先备案号的接入信息。
    • 如果您希望由42qu代备案,务必先与原先的空间商联系取消您域名的备案号, 再与42qu联系备案事宜,以避免域名备案信息冲突延误您的备案申请。

售前和售后FAQ#

  • 有Windows服务器吗?

    没有,我们只提供Linux服务器。

    至于服务器版本,您可以在多个Linux发行版中进行选择。

  • 中国南方选择哪个机房比较理想?

    42qu中国区vps使用的是北京优质的多线机房, 因此无论是电信还是联通,访问您的vps的速度都是比较理想的。

    建议vps上线后使用 http://ping.chinaz.com/ 测试您的vps的访问速度。

  • 应该如何选择不同内存大小的vps套餐?

    这取决于您的网站或应用的特点。 请发邮件到 42qu-vps@googlegroups.com 进行咨询。

  • 每个vps只分配一个ip,那么能支持多个应用吗?

    可以,使用apache或nginx做反向代理实现。

    如果您确实需要多个ip,可以联系 42qu-vps@googlegroups.com 购买。

  • 最想知道的是能支持nodejs、mongodb吗?

    您对vps具有root权限,任何软件都可以安装并正常使用。

  • 单个vps限制挂接站点的数量吗?有的话,最多几个?

    一般不做限制,但是挂太多的站点可能会影响您的站点访问速度和安全性。

  • 售后如何联系?

    请发邮件到 42qu-vps@googlegroups.com,我们会及时回应。 紧急技术响应请联系张沈鹏,18610542503

内部资料#

新机器上线流程#

做RAID 10 , 将所有硬盘整合为一个 /sda , 也就是安装系统的时候只看到一个硬盘

安装 CentOS 系统 , 选择英文 , 机器命名 为 e2 , e3 , e3 ... e5 ...

所有东西都默认

配置网卡#

进入目录 /etc/sysconfig/network-scripts

编辑或新建如下的3个文件

将其中的IP修改为机器的IP

ifcfg-eth0#

编辑如下

DEVICE="eth0"
HWADDR="00:25:90:66:3F:EE" #装完系统是什么就是什么, 不需要修改
NM_CONTROLLED="yes"
BOOTPROTO=none
ONBOOT="yes"
USERCTL=no
BRIDGE=xenbr0
ifcfg-eth1#

编辑如下

DEVICE="eth1"
HWADDR="00:25:90:66:3F:EF" #装完系统是什么就是什么, 不需要修改
NM_CONTROLLED="yes"
ONBOOT="yes"
BOOTPROTO=none
IPADDR="10.10.2.8"
NETMASK="255.255.255.0"
ifcfg-xenbr0#

编辑如下

DEVICE=xenbr0
TYPE=bridge
ONBOOT="yes"
BOOTPROTO=none
IPADDR="113.11.199.8"
GATEWAY="113.11.199.1"
NETMASK="255.255.255.0"
强氧 (supermicro x8dt6(e))BIOS 设置#
boot feature#

quick boot : enable quiet boot: disable addon rom display mode: force bios Hit ‘DEL’Messgae Display: enable wait for F1 if error: disable Interrupt 19 Capture: enable

power button function : instant off restore on ac power loss: last state watch dog function: disable

processor & clock settings#

C1E support: disable Hardware Prefetcher: disabled 失败的预取会降低性能浪费内存带宽 Adjacent Cache Line Prefetcher: disable 同上 DCU Prefetcher: disable 同上 Data Reuse Optimization: enabled MPS and ACPI MADT ordering: 默认 Modern ordering Max CPUID Value Limit: disabled Intel VIrtualization Tech: enabled Execute-Disable Bit Capability: Enabled Intel AES-NI: disable Simultaneous Multi-Threading :enabled Active Processor Cores: ALL Intel EIST tech : enabled Intel Turbo Boost: enabled Performance/Watt select: Tranditional Intel C-STATE tech : disabled clock spread spectrum: disabled

==== advanced chipset settings ========== —–CPU bridge—— QPI links speed : full QPI Frequency: auto QPI L0s and L1 : diabled

Memory Frequency: Auto Memory Mode : Independent Demand Scrubbing : disabled pratrol Scrubbing: enabled throttling - closed loop: disable

—— north bridge —– Intel I/OAT: enabled DCA tech: enabled DCA prefetch delay: 32 IOH PCI-e Max Payload size: 256B Intel VT-d: enabled active state power management: enable

IDE configuration#

Configure SATA#1 as IDE (因为有pci的raide 卡) Hot plug : eanble

PCI/ PnP#

clear NVRAM: no SR-IOV supported: enabled

Advanced ACPI#

ACPI aware O/S : yes ACPI version feature: ACPI v2 ACPI APIC support: enabled APIC ACPI SCI IRQ: enabled Headless mode: disable NUMA support: enabled WHEA support : disabled

High precision Event Timer: enabled PCIE native support: enabled

参考#

hardware prefetch is not recommanded by oracle; 有人说 c-state不稳定且降低性能;

With both sandy and the previous gen, turbo gets disabled if you disable EIST.

QPI: http://www.hardwaresecrets.com/printpage/Everything-You-Need-to-Know-About-The-QuickPath-Interconnect-QPI/610

Memory Mode: http://hardforum.com/showthread.php?t=1589710

memory scrubbing: http://www.proz.com/kudoz/english_to_spanish/computers_general/3129299-patrol_scrubbing.html

memory throttling: http://www.infoq.com/articles/power-consumption-servers

SR-IOV http://fedoraproject.org/wiki/Features/SR-IOV

42qu VPS 线上推广合作方案#

欢迎在以下位置加上我们的链接 , 以 dbanotes.net 显示豆瓣的赞助为演示

可以用 VPS返现链接 , 以获取销售提成

RSS底部链接文案建议如下

<a href=”http://vps.42qu.com“>42qu.com VPS 提供空间支持</a>

首页 & 文章页面右侧 的 样式可以参考 VPS返现链接 页面的标准样式(如下) , 文案可以自行调整

_images/side.png
首页右侧 & 文章页右侧#
_images/pic-ad.png
RSS 输出 底部#

如下图,dbanotes的rss中显示赞助商douban的广告

_images/ad-rss.png

XEN 虚拟化#

xen的文件系统是用分区呢?还是用的是文件?#

问 :
听说如果是用文件的话,xen的文件系统会差很多。。。。
答 :

2002年前用分区性能好这句话是对的;

2002年后科技发展,硬件、磁盘缓存、内核、文件系统等发展很快,用文件可以借助 host 上文件系统和内存缓存,可以提高性能。

测试结果两个差不多,用文件稍微强一点,但是用文件会方便很多,方便客户转移机房,转移 host

Thrift#

安装#

Centos 和 Ubuntu 可以直接安装 , 参见

Gentoo 安装方式 如下

emerge layman
echo 'source /var/lib/layman/make.conf' >> /etc/make.conf
layman -S
layman -a OSSDL
eix-update
emerge dev-libs/thrift

使用#

教程见

http://svn.apache.org/repos/asf/thrift/trunk/tutorial/

看 tutorial.thrift 即可

thrift –gen <language> <Thrift filename>

python 的 language 名称是 py

生成以后 看

http://svn.apache.org/repos/asf/thrift/trunk/tutorial/py/

这里 , 学习怎么写

常见问题#

如果Windows用户, 如果你下载的参考文献中 .chm 文件无法浏览 , 按下面的步骤操作即可正确查看。

css中文手册提示

关于我们#

作者:张沈鹏 zuroc.42qu.com

相关群组#

提交翻译错误、意见、建议,或加入本项目,请到 项目Github页面

相关讨论请加入 Google Groups

编写本书用到的工具#

本文档使用 reStructuredText 编写 , 语法请参见 reStructuredText 简明教程

以及

  1. Sphinx Project How-To
  2. 基于结构化文本 reStructuredText 的图书工程
  3. Quick reStructuredText

如何向本书提交自己的修改?#

项目Github页面 github.com/42qu/book , 流程下图所示

_images/book_git.png

如果不熟悉git, 和我一样是hg的用户, 可以用hg-git插件来克隆git项目 ( http://hg-git.github.com/ )

开发服务器上已经默认安装并开启 , 命令如下

hg clone git+ssh://git@github.com:zuroc/book.git

其中zuroc应该改为你自己在github的用户名 (PS:以数字开头的用hg-git用户名貌似有问题)

hg clone的时候, 会在进度条部分小卡一下, 等一等就好

其他子项目 :

十亿光年 . Tardis : 无人驾照智能车

Table Of Contents