Francis's Octopress Blog

A blogging framework for hackers.

GTD

GTD

GTD是英文Getting Things Done的缩写,是一种行为管理的方法,也是David Allen写的一本书的书名。

GTD的主要原则在于一个人需要通过记录的方式把头脑中的各种任务移出来。通过这样的方式,头脑可以不用塞满各种需要完成的事情,而集中精力在正在完成的事情。

GTD是关于什么的

和其他时间管理专家不同的是,Allen并不把重点放在设置任务的优先级。他提出制定出在各种环境下的任务列表,例如,制定一个需要打电话的列表,或者在市区才能完成的事情的列表。他也建议任何两分钟之内就能完成的任务应该马上做。

GTD在心理上的好处在于使你需要完成的事情相关的信息易于保存,跟踪和获取。Allen认为导致很多我们在做事的时候碰到的脑力上的障碍的原因是前期的计划不足(举个例子,对任何项目我们需要弄清楚要达到什么目标,还有什么措施需要完成)。

Allen认为我们的脑力上的“提醒系统”相当的低效,很少能够在恰当的时间和地点提醒我们需要做的事情。因此,把“下一步行动”根据场景分类存放在“可信的系统”当中,是一个能使我们在正确的时间得到正确的提醒的手段。在“GTD”中有很多个人的管理小技巧在实行Allen描述的工作流程中很有用的。

一个很概括的对于Allen的书的内容的描述是对于任何事情都准备好:

“把所有事情都从你的脑袋里弄出来。在事情出现,而不是在事情爆发的时候,就做好相关行动的一系列决定。以合适的类别组织好你的项目的各种提醒以及下一步的行动。保持你的系统更新和完整,充分地检查,使你在任何时候都能信任你的对于你正在做(或者不做)的事情直觉的选择。”

原则

GTD的核心原则如下:

搜集

把任何你需要跟踪或者记住或者做的事情记在Allen称之为‘水桶’的地方:一个收件箱,电子邮箱,磁带,笔记本,PDA,或者它们的组合。把你脑子里的任何东西都拿出来放到你的搜集设备里,准备好做下一步的处理。每星期所有的水桶都应该被至少清空一次。

处理

处理你的收件箱要遵循一个严格的工作流程:

  • 从最上面开始。
  • 一次处理一项。
  • 不把任何东西放回收件箱。
  • 如果任何一项需要做:
  • 做(如果花的时间少于两分钟)
  • 委托别人完成,或者
  • 把它延期。
  • 否则
  • 把它存档以便查询,
  • 把它扔掉,或者
  • 使它成熟以便下一步的处理

两分钟原则:任何事情如果花的时间少于两分钟,那么马上就去做。两分钟是一个分水岭,这样的时间和正式地推迟一个动作所花的时间差不多。

组织

Allen描述了一个建议的列表集合,你可以用来跟踪需要关注的项目:

  • 下一步行动(Next actions)- 对于每个需要你关注的事项,定好什么是你可以实际采取的下一步行动。例如,如果事项为“写项目报告”,下一步行动可能会是“给Fred发邮件开个简短会议”,或者“给Jim打电话问报告的要求”,或者类似的事情。虽然要完成这个事项,可能会有很多的步骤和行动,但是其中一定会有你需要首先去做的事情,这样的事情就应该被记录在“下一步行动”列表上。较好的做法是把这些事项根据能够被完成的“环境”整理分类,例如“在办公室”,“用电话”,“在商场”.
  • 专案(Projects)- 每个需要多于一个实际的行动才能达到的生活或者工作中的“开放式回路”就是一个“专案”.使用跟踪以及周期性的回顾来确保每个专案都有一个下一步的行动进行下去。
  • 等待(Waiting for)- 当你已经指派了一个事项给其他人或者在项目进行下去之前需要等待外部的事件,就应当在你的系统当中跟踪以及定期检查是否已经可以采取行动或者需要发出一个提醒。
  • 将来/可能(Someday/Maybe) - 这些事情你需要在某个点去做,但是不是马上。例如:“学习中文”,或者“进行一个潜水假期”.

对于跟踪你的预约和委托,一个日历也是重要的;另外,Allen特别推荐日历应该被用在他所谓的“硬工程”上:必须在某个特定的期限之前完成的事情,或者在约定的时间和地点完成的会议和约会.“待办”事项应该用在下一步行动列表当中。

GTD的最后一个关键组织模块是归档系统.“Getting Things Done”书里说如果要用一个归档系统,那它必须得是简单易用和有趣。即使是一张纸,如果你需要用来记录参考信息,如果不属于你已经有的一个目录,也要有自己的文件组织方式。Allen的建议是你可以维护一个按照字母顺序组织的归档系统,这样可以比较容易快速的存储和提取你所想要的信息。

Google的Gmail的用户可以用创建标签的方式来创建“待办事项”和“项目”,这种方式在Bryan Murdaugh的 “Getting Things Done with Gmail” [1]白皮书中有清楚的描述。它保留了很多GTD的相同概念,但是是在在线的电子邮件系统中实施。

检查

如果你不至少每天或者只要你有时间就回顾检查,那么你的行动和提醒的列表将会变的毫无用处。以你当时拥有的精力,资源和时间,决定什么是对你来说最重要的事情,然后做。如果你倾向于拖延,你可能会老是做最容易的事情,避免那些难的。为了解决这个问题,你可以一个接一个地做列表上的事情,按照它们的顺序,就象你处理你的收件箱一样。

至少以星期为周期,GTD要求你回顾所有你比较主要的“行动”,“项目”和“等待”的事项,确保所有的新任务或者即将到来的事件都进入你的系统,而且所有的事情都更新到符合最新的情况。Allen建议制作一个难题档案来帮助你更新你关于主要行动的记忆。

如果你把你的时间都花在组织工作,而不是做它们,那么所有的GTD系统都是不好用的!David Allen的观点是,如果你可以把必须做的事情,让它变得简单、容易、有趣的话,那你就比较不会拖延、或者被太多的“开放性回路”所压倒。

 工具和技巧

一个Allen推荐的工具是难题文件夹,用来组织你的GTD的文字工作(也被称为‘43文件夹’).12个文件夹用来表示每一个月,另外的31个文件夹用来表示每一天。这些文件夹用来帮助提醒你当天的活动。每天你打开表达当天的文件夹。你把所有的事项都拿出文件夹,然后把空文件夹放进下一个月里。这种处理允许你为自己保存提醒的硬拷贝。例如,如果你在这个月的12号有一个音乐会,你可以把票放在第12个文件夹当中。当12号到的时候,它就在那里等着你。

DIY Planner Hipster PDA

这是一种用来执行GTD的纸本DIY范本,对于习惯用实体纸本计划的人来说,可作为另一种优质选择。[2]

 引用

十个免费的Web压力测试工具

十个免费的Web压力测试工具

relate resources:

如何测试 rails 网站在高并发下的性能?

两天,jnj在本站发布了《如何在低速率网络中测试 Web 应用》,那是测试网络不好的情况。而下面是十个免费的可以用来进行Web的负载/压力测试的工具,这样,你就可以知道你的服务器以及你的WEB应用能够顶得住多少的并发量,以及你的网站的性能。我相信,北京奥组委的订票网站的开发团队并不知道有这样的测试工具。

Grinder –  Grinder是一个开源的JVM负载测试框架,它通过很多负载注射器来为分布式测试提供了便利。 支持用于执行测试脚本的Jython脚本引擎HTTP测试可通过HTTP代理进行管理。根据项目网站的说法,Grinder的 主要目标用户是“理解他们所测代码的人——Grinder不仅仅是带有一组相关响应时间的‘黑盒’测试。由于测试过程可以进行编码——而不是简单地脚本 化,所以程序员能测试应用中内部的各个层次,而不仅仅是通过用户界面测试响应时间。

Pylot -Pylot是一款开源的测试web service性能和扩展性的工具,它运行HTTP 负载测试,这对容量计划,确定基准点,分析以及系统调优都很有用处。Pylot产生并发负载(HTTP Requests),检验服务器响应,以及产生带有metrics的报表。通过GUI或者shell/console来执行和监视test suites。

Web Capacity Analysis Tool (WCAT) – 这是一种轻量级负载生成实用工具,不仅能够重现对 Web 服务器(或负载平衡服务器场)的脚本 HTTP 请求,同时还可以收集性能统计数据供日后分析之用。WCAT 是多线程应用程序,并且支持从单个源控制多个负载测试客户端,因此您可以模拟数千个并发用户。该实用工具利用您的旧机器作为测试客户端,其中每个测试客户 端又可以产生多个虚拟客户端(最大数量取决于客户端机器的网络适配器和其他硬件)。您可以选择使用 HTTP 1.0 还是 HTTP 1.1 请求,以及是否使用 SSL。并且,如果测试方案需要,您还可以使用脚本执行的基本或 NTLM 身份验证来访问站点的受限部分。(如果您的站点使用 cookie、表单或基于会话的身份验证,那您可以创建正确的 GET 或 POST 请求来对测试用户进行身份验证。)WCAT 还可管理您站点可能设置的任何 cookie,所以配置文件和会话信息将永久保存。

 

fwptt – fwptt 也是一个用来进行WEB应用负载测试的工具。它可以记录一般的请求,也可以记录Ajax请求。它可以用来测试 asp.net, jsp, php 或是其它的Web应用。

JCrawler – JCrawler是一个开源( CPL) 的WEB应用压力测试工具。通过其名字,你就可以知道这是一个用Java写的像网页爬虫一样的工具。只要你给其几个URL,它就可以开始爬过去了,它用一 种特殊的方式来产生你WEB应用的负载。这个工具可以用来测试搜索引擎对你站点产生的负载。当然,其还有另一功能,你可以建立你的网站地图和再点击一下, 将自动提交Sitemap给前5名的搜索引擎!

Apache JMeter – Apache JMeter是一个专门为运行和服务器装载测试而设计的、100%的纯Java桌面运行程序。原先它是为Web/HTTP测试而设计的,但是它已经扩展以 支持各种各样的测试模块。它和用于HTTP和SQL数据库(使用JDBC)的模块一起运送。它可以用来测试静止资料库或者活动资料库中的服务器的运行情 况,可以用来模拟对服务器或者网络系统加以重负荷以测试它的抵抗力,或者用来分析不同负荷类型下的所有运行情况。它也提供了一个可替换的界面用来定制数据 显示,测试同步及测试的创建和执行。

Siege -Siege(英文意思是围攻)是一个压力测试和评测工具,设计用于WEB开发这评估应用在压力下的承受能力:可以根据配置对一个WEB站点进行多用户的 并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行。 Siege 支持基本的认证,cookies, HTTP 和 HTTPS 协议。

http_load – http_load 以并行复用的方式运行,用以测试web服务器的吞吐量与负载。但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会把客户机搞死。可以可以测试HTTPS类的网站请求。

Web Polygraph – Web Polygraph这个软件也是一个用于测试WEB性能的工具,这个工具是很多公司的标准测试工具,包括微软在分析其软件性能的时候,也是使用这个工具做为基准工具的。很多招聘测试员的广告中都注明需要熟练掌握这个测试工具。

OpenSTA – OpenSTA是一个免费的、开放源代码的web性能测试工具,能录制功能非常强大的脚本过程,执行性能测试。例如虚拟多个不同的用户同时登陆被测试网 站。其还能对录制的测试脚本进行,按指定的语法进行编辑。在录制完测试脚本后,可以对测试脚本进行编辑,以便进行特定的性能指标分析。其较为丰富的图形化 测试结果大大提高了测试报告的可阅读性。OpenSTA 基于CORBA 的结构体系,它通过虚拟一个proxy,使用其专用的脚本控制语言,记录通过 proxy 的一切HTTP/S traffic。通过分析OpenSTA的性能指标收集器收集的各项性能指标,以及HTTP 数据,对系统的性能进行分析。

欢迎您留下你认为不错的WEB应用性能测试的工具。

16 Impressive CSS3, HTML5 and Javascript Experiments From Hakim

16 Impressive CSS3, HTML5 and Javascript Experiments From Hakim

If you’re a fan of Canvas, WebGL and interactive CSS3, HTML5 and Javascript, you most probably have heard of the name Hakim. Hakim is a web developer and creative programmer from Sweden who passionate about working with animation and interactivity. He has many personal projects and experiments with HTML5, CSS and Javascript showcased in Chrome Experiments and other places. We are really impressed but his creativity and cool stuff that he managed to create, and the following is some of the coolest things on the web.

  • CSS3 Scroll EffectCool list scrolling effect. Not intended for any practical use but the visuals are surprisingly impactful. CSS3 Scroll Effect
  • DOM TreeChristmas Pine Tree wit form elements. DOM Tree
  • OrigamiSimply a colorful folding doodle on. Click anywhere on the drawing – or use your keyboard – to activate different layouts. Origami
  • .net 404A creepy 404 page for .net magazine. .net 404
  • SphereThe sphere – actually more of a spiral – is built out of 10,000 particles and the structure changes over time. Sphere
  • Textify.itBrowser for or drag an image onto the page and watch it be reconstructed purely out of text. The markup for the resulting textual image can be copied and used elsewhere. Textify.it
  • WebGL ParticlesAn experiment created to test the efficiency of particles rendering with WebGL. WebGL Particles
  • BreakDOMThis is a remix of the classic Breakout game except all game elements have been replaced with HTML user interface elements. BreakDOM
  • SinuousA game built on the HTMLCanvas element which will test your mouse pointer reflexes. The objective is to stay clear of the evil red dots and stay alive as long as possible. Sinuous
  • MagneticControl and create currents of particles which react to magnetic nodes. Magnetic
  • WaveA wave with bubbles floating on the surface, the bubbles each represent a tweet with the word “water” in it. Wave
  • TrailParticle movement patterns that generate smooth trails. Trail
  • BlobSoft blobby physics. It’s like, you know… jelly? Blob
  • BacteriumAn interactive experiment with bacteria in a playful and dynamic physics world. Bacterium
  • Particle DepthParticle positioning patterns using depth. Particle Depth
  • KeylightA playhead travels between keys which resonate in sound depending on where they are placed in the room. Keylight

Markdown语法

Markdown语法

概述

哲学

Markdown 的目标是易读易写。

Markdown强调可读性高于一切。一份Markdown格式的文档应该能直接以纯文本方式发布,而不致一眼看过去满眼都是标签和格式化指令。Markdown的语法确实受了几种现有的text转HTML过滤器影响--包括 Setext, atx, Textile, reStructuredText,Grutatext, 和 EtText — 其中对Markdown语法影响最大的单一来源是纯文本的Email格式。

为实现这一目标,Markdown的语法几乎全部由标点符号构成,这些标点符号都是精心挑选而来,尽量做到能望文生义。如星号括着一个单词(Markdown中表示强调)看上去就像 强调。Markdown的列表看上去就像列表;Markdown的引文就象引文,和你使用email时的感觉一样。

内嵌HTML

Markdown的语法为“方便地在网上写作”这一目标而生。

Markdown不是HTML替代品,也不是为了终接HTML。它的语法非常简单,只相当于HTML标签的一个非常非常小的子集。它并非是为了更容易输入HTML标签而创造一种新语法。在我看来,HTML标签已经够容易书写的了。Markdown的目标是让(在网上)让读文章、写文章、修改文章更容易。HTML是一种适合发表的格式;而Markdown是一种书写格式。正因如此,Markdown的格式化语法仅需解决用纯文本表达的问题。

对Markdown语法无法支持的格式,你可以直接用HTML。你不需要事先声明或者使用什么定界符来告诉Markdown要写HTML了,你直接写就是了。

唯一的限制是那些块级HTML元素 — 如 <div>,<table>, <pre>, <p>等等 — 必须使用空行与相邻内容分开,并且块元素的开始和结束标签之前不要留有空格或TAB。Markdown足够聪明不会添加额外的(也是不必要的)<p>标签包住这些块元素标签。

下面这个例子,在一篇Markdown文章中添加了一个HTML表格:

这是一个普通的段落。 <table> <tr> <td>Foo</td> </tr> </table> 这是另一个普通的段落。

注意一点,不要在块级HTML元素内使用Markdown格式化命令,Markdown不会处理它们。比如你不要在一个HTML块中使用 emphasis 这样的Markdown格式化命令。

行内HTML标签 — 如 <span>, <cite>, 或 <del> — 在一个Markdown段落里、列表中、或者标题中--随便用。 如果需要,你甚至可以用HTML标签代替Markdown格式化命令。比方你可以直接用HTML标签 <a><img> 而不使用Markdown的链接和图片语法,随你的便。

不同于这些块级HTML元素,在HTML行内元素内的Markdown语法标记会被正确处理。

自动转换特殊字符

在HTML中,有两个字符需要特殊对待:<&<用于标签开始,&用于标识HTML实体。如果打算把它们当成普通字符,你必须使用反引号转义它们,如<&

对一些互联网作家来说,&符号特别使人烦恼。如果你打算写’AT&T’,你就得写 ‘AT&amp;T‘。甚至在URL中也得想着转义&符号。比方你打算写:

http://images.google.com/images?num=30&q=larry+bird

你就得在A标签中把href属性中的URL编码成:

http://images.google.com/images?num=30&amp;q=larry+bird

不用说,这很容易忘。这往往是那些良构HTML站点中最容易出错的地方。

在Markdown中,你尽管自然的使用这些字符,只需要关心那些必要的转义。如果使用在HTML实体中使用&符号,它会保持不变;而在其它场合,它会转换成&

所以,如果你打算在文章中书写版权符号,你可以这样写:

&copy;

Markdown不会碰它。然而如果你书写

AT&T

Markdown就会把它翻译成:

AT&amp;T

类似的,既然Markdown支持内嵌HTML,如果你使用<作为HTML标签定界符,Markdown就会把它们当成HTML标签定界符。可是如果你书写:

4 < 5

Markdown就会把它翻译成:

4 &lt; 5

然而,在Mardown代码行内标记和块级标记之中,<&始终会被自动编码。这使得在Markdown文件中书写HTML代码更容易.(相对于纯HTML。如果想在纯在纯HTML里贴一段HTML代码,那才是糟糕透顶,必须对代码中的每一个<&都转义才成。)


块级元素

段落和换行

一个段落由一行或多个相关文本行构成。段落之间用一个或多个空行分隔。(一个空行就是一个看上去什么也没有的行--如果一行什么也没有或者只有空格和TAB都会被视为空行)正常的段落不要以空白或TAB字符开始。

一行或多个相关文本行意味着Markdown支持“硬折行”。这一点与其它text转HTML的程序完全不同(包括Moveable Type的“Convert Line Breaks”选项),它们会将段落中的每一个换行符转换成<br />标签。

如果你确实需要使用Markdown插入一个<br />换行符,只需要在每一行的末尾以两个或更多个空格符号结束,然后再打回车键。

没错,在Markdown里生成一个<br />稍稍有一点麻烦,但那种简单的“把每一个换行符都转换成<br />规则”并不适用于Markdown。Markdown Email风格的 blockquoting 和 multi-paragraph list items更好用 — 并且更美观 — 在你用换行符对其格式化时。

Markdown 支持两种风格的标题,Setextatx.

Setext-风格的一级标题下面一行使用等号符号,二级标题下面使用连字符符号,例如:

这是一个一级标题 ============= 这是一个二级标题 -------------

至少有一个=就能正常工作。

Atx-风格的标题在每行的开头使用1-6个井号字符,分别对应标题级别1-6。例如:

# 这是一级标题 ## 这是二级标题 ###### 这是六级标题

如果愿意, 你也可以 “结束” atx-风格的标题。这纯粹是美观考虑—如果你觉得这样会看上更舒服些的话。结束用的井号个数随便,不必与起始井号数量相同 (起始井号的数量决定标题级别):

# 这是一级标题 # ## 这是二级标题 ## ### 这是三级标题 ######

引用块

Markdown使用Email风格的 > 字符引用块。如果你熟悉Email中的引用块,你就知道在Markdown中如何使用引用块。如果每一行你都使用硬换行并在行首放一个>符号,看上去会很美观:

> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse > id sem consectetuer libero luctus adipiscing.

(如果觉得每行写一个>太累,)Markdown允许你偷懒,你只需在硬换行段落的第一行之前放一个>号:

> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

只需要多加一个>,就得到嵌套的引用块(即引用块中的引用块):

> This is the first level of quoting. > > > This is nested blockquote. > > Back to the first level.

引用块中可包含其它Markdown元素,如标题、列表和代码块:

> ## This is a header. > > 1. This is the first list item. > 2. This is the second list item. > > Here's some example code: > > return shell_exec("echo $input | $markdown_script");

是个象样的文本编辑器都能实现Email风格的引用。比如在BBEdit里,你就可以选中一些文字之后从Text菜单里选择引用级别。

列表

Markdown 支持有序列表和无序列表

无序列表可使用星号、加号和连字符(这几个符号是等价的,你喜欢哪个就用哪个)作为列表标记:

* Red * Green * Blue

等同于:

+ Red + Green + Blue

也等同于:

- Red - Green - Blue

有序列表则使用数字加英文句点:

1. Bird 2. McHale 3. Parish

有一点需要注意,你在列表中输入的标记数字并不会反映到Markdown输出的HTML之中。上面这个列表Markdown会输出为:

<ol> <li>Bird</li> <li>McHale</li> <li>Parish</li> </ol>

即使你写成下面这样:

1. Bird 1. McHale 1. Parish

甚至这样:

3. Bird 1. McHale 8. Parish

都会得到一模一样(但正确的)输出。要点在于,如果你愿意,就在你的Markdown有序列表里顺序使用数字(这样源代码里的顺序和生成的顺序会一致),如果你希望省点儿事,你就不用费心(去手工编号)。

如果你打算偷懒,记住列表的第一行使用数字 1。以后Markdown或许会支持有序列表从任意数字开始(译者注:这儿和前面的例子有点矛盾,原文如此)。

列表标记通常从左边界开始,至多可以有三个空格的缩进。列表标记之后至少要跟一个空格或TAB。

为了让列表看起来美观,你可以使用TAB缩进列表项内容,使其整齐:

* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

不过如果你很懒,下面这样也行:

* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

如果列表项之间用空行分隔,Markdown就会在HTML输出中使用<p>标签包裹列表项。比如:

* Bird * Magic

生成的HTML如下:

<ul> <li>Bird</li> <li>Magic</li> </ul>

而这个:

* Bird * Magic

生成的HTML是这样:

<ul> <li><p>Bird</p></li> <li><p>Magic</p></li> </ul>

列表项有可能由多个段落组成,列表项的每个后续段落必须缩进至少4个空格或者一个TAB:

1. This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. 2. Suspendisse id sem consectetuer libero luctus adipiscing.

像上面这样缩进后续段落的每一行看起来很美观(但稍有些麻烦),如果你比较懒(和我一样),没问题,Markdown支持你:

* This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. * Another item in the same list.

要在列表项中使用引用,引用定界符 > 需要缩进:

* A list item with a blockquote: > This is a blockquote > inside a list item.

要在列表项中使用代码块,代码块需要缩进两次 — 8个空格或者两个TAB:

* A list item with a code block: <code goes here>

有时候不小心会触发一个有序列表,比方在写类似下面这样的东西时:

1986. What a great season.

换言之, 以数字+句点+空格 序列起始的行会触发有序列表。为避免此情况,要对句点符号进行转义:

1986\. What a great season.

代码块

我们经常在写有关编程或标记语言源代码时用到预格式化的代码块。不像格式化普通段落,代码块中的行会按字面进行解释。Markdown对代码块同时使用<pre><code>标签包裹:

在Markdown中要生成一个代码块,只需要在代码块内容的每一行缩进至少四个空格或者一个TAB。比如:

This is a normal paragraph: This is a code block.

Markdown会生成:

<p>This is a normal paragraph:</p> <pre><code>This is a code block. </code></pre>

Markdown会从生成的代码块中删除一级缩进 — 4个空格或者1个TAB。看下面这个例子:

Here is an example of AppleScript: tell application "Foo" beep end tell

会得到:

<p>Here is an example of AppleScript:</p> <pre><code>tell application "Foo" beep end tell </code></pre>

代码块在遇到没有缩进的一行,或者文件末尾时自动结束。

在代码块中,&符号和<>会自动转换成HTML实体。因此在Markdown中包含HTML源代码只是小菜一碟--粘贴进去,缩进一下。剩下的脏活累活Markdown自会处理。看下面这个例子:

 <div class="sample_footer"> &copy; 2004 Foo Corporation </div>

Markdown会生成:

© 2004 Foo Corporation
 

 

Markdown不会解析代码块中的Markdown标记。如代码块中的星号就是星号,失去了它原来的Markdown含义。这意味着你能够使用Markdown编写Markdown自己的语法教程。(就象这篇文章一样)。

水平线

如果在一行里只放三个或更多个连字符,或星号或下划线,你就会得到一个水平线标记(<hr />)。下面每一行都会得到一个水平线:

* * * *** ***** - - - ---------------------------------------

行内元素

Markdown 支持两种风格的链接: 行内链接引用链接.

两种风格的链接,链接文本都放在中括号之内[square brackets]。

要生成一个行内链接,在链接文本之后紧跟用一对小括号。小括号里放链接地址和可选的的链接title。如果提供链接title的话,链接title要用引号包起来。例如:

这是一个 [an example](http://example.com/ "Title") 行内链接。 [这个链接](http://example.net/) 没有title属性。

Markdown会生成:

<p>This is <a href="http://example.com/" title="Title"> an example</a> inline link.</p> <p><a href="http://example.net/">This link</a> has no title attribute.</p>

如果你打算引用一个本地资源或者同一站点的资源,可以使用相对路径:

如果想进一步了解我,请参阅我的 [关于我](/about/) 页。

引用风格的链接,在链接文本之后紧跟又一对中括号。这对中括号里放的是该链接的标识符(可以理解为别名):

这是一个引用型链接 [示例][id]。

如果你嫌弃两对中括号过于亲密,Markdown允许你在两对中括号之间放一个空格:

这是一个引用型链接 [示例] [id]。

然后,我们可以在文档的任意位置,像下面这样定义链接标识与链接的对应关系(一行一个链接):

[id]: http://example.com/ "Optional Title Here"

即:

  • 中括号内放链接标识符(行前可选缩进,至多不超过三个空格);
  • 之后紧跟一个冒号;
  • 再后面是一个或多个空格(TAB也行);
  • 接下来是链接URL;
  • 最后面是可选的用双引号或单引号或小括号括起来的链接title。

下面三种链接定义方式是等价的:

[foo]: http://example.com/ "Optional Title Here" [foo]: http://example.com/ 'Optional Title Here' [foo]: http://example.com/ (Optional Title Here)

注意: Markdown.pl 1.0.1 版本有一个已知的bug,用单引号作为链接title的定界符会出问题。

至于链接URL,还支持使用一对可选的尖括号包裹起来:

[id]: <http://example.com/> "Optional Title Here"

你也可以将链接的title属性放在下一行并使用额外的空格或TAB填充,这样较长的URL会比较美观:

[id]: http://example.com/longish/path/to/resource/here "Optional Title Here"

链妆定义仅供Markdown解析器使用。最终输出的HTML当中不会包含链接定义。

链接标识符可以由字母、数字、空格和标点符号组成--不区分大小写。下面这两个链接:

[link text][a] [link text][A]

是等价的。

隐式链接标识 允许我们省略链接标识,这时链接文本本身就是链接标识。在链接文本之后加一对空的中括号--例如,使用”Google”文本链接到google.com站点,可以这样写:

[Google][]

然后这样定义它的链接:

[Google]: http://google.com/

链接名字有可能包含空格,不过没问题,这种情况照样正常工作:

Visit [Daring Fireball][] for more information.

然后这样定义这个链接:

[Daring Fireball]: http://daringfireball.net/

链接定义可放于Markdown文档的任意位置。我建议把它们就近放到最先使用它的段落之后。不过如果你更喜欢放到文档末尾,当成某种形式的尾注,随你的便。

下面是一些引用链接的例子:

I get 10 times more traffic from [Google] [11] than from [Yahoo] [12] or [MSN] [13]. [1]: http://google.com/ "Google" [2]: http://search.yahoo.com/ "Yahoo Search" [3]: http://search.msn.com/ "MSN Search"

换成隐式链接标识,也可以这么写:

I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][]. [google]: http://google.com/ "Google" [yahoo]: http://search.yahoo.com/ "Yahoo Search" [msn]: http://search.msn.com/ "MSN Search"

上面两种写法最终得到HTML输出是一样的:

<p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>

作为比较,下面这个段落使用Markdown的行内链接风格编写:

I get 10 times more traffic from [Google](http://google.com/ "Google") than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or [MSN](http://search.msn.com/ "MSN Search").

引用型链接的亮点并不在于它更容易书写,而在于引用型链接让你的文档可读性更好。看看上面的例子:使用引用型链接,段落本身仅81个字符;而使用行内链接的例子,是176个字符。最终输出的HTML则有234个字符。纯HTML中标记字符甚至超过了文本本身。

使用Markdown的引用型链接,源文档更接近于最终的浏览器输出效果。再加上Markdown允许将标记有关的元数据移到段落之外,你尽管添加链接,而不必担心打断文件的故事情节。

强调

Markdown使用星号()和下划线(_)作为表示强调。用一个 包裹的文本会使用 HTML <em> 标签包裹; 用两个 *包裹的文本会使用HTML<strong> 标签包裹。如:

*single asterisks* _single underscores_ **double asterisks** __double underscores__

将会输出为:

<em>single asterisks</em> <em>single underscores</em> <strong>double asterisks</strong> <strong>double underscores</strong>

你喜欢哪一种风格就用哪一种,唯一的限制就是起始字符与关闭字符必须一致。

强调符号可用于一个单词的一部分:

un*frigging*believable

不过如果你用空格包裹单独的 *_,它们就失去了强调的含义,而成为字面上的星号或下划线。

如果不想让Markdown解释这两个元字符,就转义它:

\*this text is surrounded by literal asterisks\*

代码

要在行内表示部分代码,用反引号(`)包住它。与预格式代码块不同和,行内代码用于段落之内。例如:

Use the `printf()` function.

会生成:

<p>Use the <code>printf()</code> function.</p>

要在一个行内代码中使用反引号(`)本身,用多个反引号作为定界符包住它:

``There is a literal backtick (`) here.``

这样就会得到:

<p><code>There is a literal backtick (`) here.</code></p>

包住行内代码的反引号定界符可以包括空格--即在起始反引号之后,结束反引号之前可以有一个空格。这使得我们能够在行内代码的开始或结束处使用反引号:

A single backtick in a code span: `` ` `` A backtick-delimited string in a code span: `` `foo` ``

会生成:

<p>A single backtick in a code span: <code>`</code></p> <p>A backtick-delimited string in a code span: <code>`foo`</code></p>

在行内代码中,&<>会自动编码为HTML实体,以方便包含HTML标签。Markdown会把下面这行:

Please don't use any `<blink>` tags.

转换为:

<p>Please don't use any <code><blink></code> tags.</p>

你也可以这样写:

`&#8212;` is the decimal-encoded equivalent of `&mdash;`.

会得到:

<p><code>&#8212;</code> is the decimal-encoded equivalent of <code>&mdash;</code>.</p>

图片

必须承认,要以“自然的”语法把一个图片放到一个纯文本文档之中,确实是一个挑战。

Markdown使用了类似链接语法来表示图片,同样有两种风格:行内图片引用图片

行内图片语法示例:

![Alt text](/path/to/img.jpg) ![Alt text](/path/to/img.jpg "Optional title")

即:

  • 一个感叹号!开头;
  • 其后紧跟一对中括号,中括号内存放图片的alt`属性;
  • 其后紧跟一对小括号,小括号内存放图片的URL或路径,及可选的用双引号或单引号或小括号括起来的图片title

引用图片语法如下:

![Alt text][id]

这里 “id” 是图片引用标识。图片引用定义的语法与链接定义完全相同:

[id]: url/to/image "Optional title attribute"

在写这篇文章时,Markdown还没有语法指定图片的大小,如果这一点对你特别重要,你可以直接使用<img>标签。


杂七杂八

Markdown提供了一种快捷方式”自动地”定义链接和Email地址:直接用一对尖括号把URL或Email地址包住。这表示链接文本就是URL本身,Email文本就是Email本身。这样你就得到了一个可点击的链接,如:

<http://example.com/>

Markdown会将它转换为:

<a href="http://example.com/">http://example.com/</a>

自动Email地址工作方式相似,只有一点不同。Markdown自动的用一些十进制和十六进制数字表示你的Email,以防止遭遇垃圾邮件袭击。 例如:

<address@example.com>

会被转换为:

<a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65; &#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111; &#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61; &#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>

浏览器会将它渲染为一个可点击的链接,并正确显示 “address@example.com“。

(这种实体编码的小方法可以骗过一些收集邮件地址的机器人,不过它确实无法骗过所有的机器人。有总比没有强,聊胜于无。能阻止一点就阻止一点好了。)

反斜线转义

Markdown允许你使用反斜线转义那些Markdown元字符,让它们失去原有的“魔力”。举个例子,如果你确实想用星号包住一个词组(而不是想得到<em>标签),就可以在星号之前使用反斜线将其转义。即:

\*literal asterisks\*

Markdown中,以下字符支持使用反斜线转义:

\ 反斜线 ` 反引号 * 星号 _ 下划线 {} 大括号 [] 中括号 () 小括号 # 井号 + 加号 - 减号(连字符) . 句点 ! 感叹号

你不必这么着急 –by Rei

你不必这么着急 —by Rei

现在这个世界,似乎一切都在快速演进:各种年少暴富的新闻充斥着我们的眼球,软件开发世界到处是敏捷方法,甚至你最亲近的人都在催促你更快——谁谁谁都已经XX了,你将来怎么打算?所以,现在的学生找实习的时间越来越早,想速成的心态越来越重。

但是,你不必这么着急。慢有慢的好处,最重要的是,急也急不来。我想和未走出社会的人分享一下,为什么是我们不用那么着急,并且应该把精力放去哪里。如果你已经工作数年了,但是对着未来感到恐惧,却从来没有试着让自己慢一点,也可以看一看接下来的内容。

在继续阅读之前,先看几个问题,判断这篇文章是否适合你。

  1. 并不是所有人都那么聪明的,有些人只需要过普通的生活就够了。

对的,但我只想跟觉得自己足够聪明的人讨论后面的内容。实际上,我觉得没有什么聪不聪明之分,只是投入时间的问题。

  1. 不是所有人都有那么崇高的理想的,这些内容太理想主义了。

对的,但我也是只想跟心怀理想的人交流。

  1. 我负有助学贷款压力/出身贫寒/其他急需资金的原因,没空让我停下来好好考虑。

很遗憾,这部分人可能需要先解决温饱问题,待将来走出了困境,再仔细考虑一下前面的内容。

你没有对上面的内容嗤之以鼻,那么,可以进入正题了。

为什么你不用这么着急

这里有着确切的理由,你不用这么着急

1. 工作岗位比你想象中多

对于真正的人才,工作机会是源源不断的。他们困扰的不是找工作,而是找有趣的工作。这听起来很气人,大学毕业有很多人找不到工作呢,很多人工作几年还在用“码农”调侃自己呢。

但现实就是这样,企业缺人、缺人才,但是不缺平凡的人。企业发出一个招聘岗位,会收到数十上百封简历,但十有八九在第一轮人事MM筛选中就会去掉,真正到达缺人部门的领导手中时,又是十有八九看一眼就被淘汰掉了……等等,这是不是说找工作很难呢?正好相反,看问题得反过来看。

试想你是一个部门领导,你的部门急需补充成员,否则会拖慢年度的计划安排。一个月两个月过去了,总看不到可塑之才出现。所以你得不断地到人事部催促,多发些招聘信息;人事MM每天被催促,恨不得天上掉下个技术大牛,活好收费少,赶紧把招聘任务了结了。这样的部门、这样的公司都处都是,他们都在焦急的等着那些合适的人。如果你恰好是那类人,入职就是一张机票的事。

记住,关键是你是否能成为合适的人。“找”工作是没用的,只会成为那 (9/10 + 1/10 × 9/10) × 100%。最理想的是,让工作来找你,这放在后面说。

2. 现实工作不一定有趣

假设你已经足够成为那类公司热烈欢迎的人了,是不是得赶紧走出社会“积累积累”经验了呢?

我给建议依然是:别急。现实工作不一定有趣,无趣的工作意味着工作效率低下,工作效率低下意味着经验增长缓慢,经验增长缓慢的工作,还不知蹲在家里每天写8个小时代码呢。

一般说来,越大的公司越无趣,因为大公司有复杂的流程。如果你的工作环境被切割成了设计-UI-编码的团队界限分明的结构,那么你的发挥空间就很小了。你的最大目标是实现别人的需求,你需要实现很繁琐的注册表单和根本没人会用的后台控制;你需要在每个a标签里面放一些不必要的span;你需要学会写 ugly 的代码,因为时间紧/反正用得很好/要跟周围风格一致。另一方面,小公司也会让你很无趣,你需要做运维/产品/设计/编码/维护,半夜收到异常Email要起床,还要吃着老板画给你的“等公司上了轨道一定不会亏待你的”的大饼。

天阿,让不让人活了!

其实分辨工作是否有趣很简单:招人最靠谱的是看作品,找工作最靠谱的当然就是看产品了。看公司的产品,你觉得有不有趣,你自己会不会用,细节做得好吗,是又一个 C2C(Copy to China) 吗?从公司的产品,就可以看出公司的内部架构和流程,员工工作得愉不愉快,创意有没有施展的空间。我觉得,Twitter,Github 那样的公司就挺好。

要去,就要去有趣的公司,世界上缺工作的人那么多,为什么要跟他们争抢一份平凡的工作呢?

把精力花到刀刃上

如果你接受了我上面说的理由,那么可以淡定的看待身边一个又一个找到实习或者工作的同学了,因为你需要认真地挖掘什么才是你需要持久钻研的东西。

1. 多参与开源项目

github.com 不用多说了,现在已经成为技术人员最好的简历。

有了 github,参与开源项目成为一件很简单的事情:使用 –> 发现 bug –> 查找/提交 issues –> 提交 pull-request。

不过,要一开始就参加一个热门的项目是很困难的,因为有很多比你聪明(本质只是编程时间比你长)的人都在上面折腾,根本没有让你“接球”的机会。

这时候最好自己发展一个开源项目。

可以练手的项目类型多着呢:你的博客/Todo-list好用吗?你觉得某个现有的服务/项目很搓吗?你需要帮你随机决定中午午餐吃什么而且自动发送邀请给好友的机器人程序吗?

发挥你的想象力,做一个实际能用的项目,比到公司打杂有用多了。

2. 多参与社区讨论

你得了解你学习的技术方向的牛人在哪里混,多跟他们交流,也多回答新手的提问,在网络社区里很有可能你会遇到你将来的同事或者合伙人。

编程是一项社会活动,即使你的程序完全是交给机器执行,但是最终的使用者和受益者是人类,所以你需要认识各种各样的人,了解你是为了什么去编程。

如果你学习 Ruby,我推荐 ruby-china.org,这是当前国内人气最旺的 Ruby 社区了。当然,还有 CodeCampo,你可以看到 Rei 分享的各类奇怪资源。

3. 多进行户外活动

多进行户外活动,即可以强健体魄,也可以让你的性格更开朗。性格开朗的人,创造力会比整天闷闷不乐的人高。这里就有一个乐天向上好榜样:辞职旅行一周年

勇敢的编程 10000 小时

程序世界是非常公平的,随着你编程经验的积累,你的项目用户会开始增多,你的交友圈会更广泛,你的工作机会会找上门——或者该你给别人工作机会了。

无论怎么样,要成为技术牛人,编程 10000 小时是少不了的。无论你愿不愿意,你的经验都在增加,所以你完全不用心急。

看清自己的目标,一步一步的走,有一天它就会在你脚下。

Git Submodule 的認識與正確使用!

Git Submodule 的認識與正確使用!

已經用了 git submodule 好一陣子了,今天看到了 Git submodules in N easy steps 才覺得比較搞懂一些之前碰到的問題。趁機來整理、釐清之前常碰到的小問題吧~~

什麼是 Git Submodule

剛剛從 SVN 或 CVS 等 Client-Server 架構的版本控制系統切換到 Git 時,可能會有這個想法:「能不能只取得一部分的程式碼、而非整個 Repository?」因為在 SVN/CVS 可以針對 Repository 中的某個目錄 checkout,不需要是整個 Repository、甚至還可以用 SVN Externals 達到不同角色 (視覺、前端、後端)checkout 不同 File Layout(之前在無名小站時,超喜歡 svn:externals 的概念)。 但 Git 是分散式的版本控制系統,每個人都是一個完整的 Repository,沒辦法像 SVN/CVS 指定到某個資料夾。例如你要取得 YUI 3 的 Git,只能 git clone https://github.com/yui/yui3.git、而不能指定到底下的目錄。 SVN/CVS 你可以用目錄區隔大小專案、都在同一個大的 Repository。而 Git 的想法必須修正為每個小專案就是一個 Repository、或不同團隊開發是一個 Repository、甚至功能獨立也可以是一個 Repository。若說 SVN 是包容百川、Git 就是各自獨立的小河流。 但軟體開發團隊不太容易如此單純,有時需要給外包開發、有時需要分工、有時需要用 Open Source,光用以上的切分方式是沒辦法達成所有需求的、還是得將各自獨立的小河流連接起來。例如我先前在 WebRebuild 與 COSCUP 分享的 JavaScript Platform,為了分享把原始碼放了一份到 Github : http://github.com/josephj/javascript-platform-yui,但我的工作及部落格都有使用的需求,該怎麼做呢?如果每次都得 git clone 再 copy 檔案到兩個地方、這樣手工做真的是個很遜的解決方案。好在有 Git Submodule 可以幫忙解決! 簡單來說,Git Submodule 可以輕易地將別人的 git 掛入到你目前 git 的任何位置

新增一個 Git Submodule

例如我有目前本機有一個 josephj.git、在 /home/josephj/www 下,而我需要將 javascript platform 放到 /home/josephj/www/static/ 可以用以下幾行快速達成。
  • 切換到我的 repository 目錄: $ cd /home/josephj/www
  • 使用 git submodule add [repository 位置] [欲放置的位置] 增加一個新的 submodule: $ git submodule add git@github.com:josephj/javascript-platform-yui.git static/platform需要注意 [欲放置的位置] 不能以 / 結尾(會造成修改不生效)、也不能已經是現有的路徑喔(不能順利 Clone)。
  • 按下去就會看到以下結果:
    $ git submodule add git://github.com/josephj/javascript-platform-yui.git static/platform Initialized empty Git repository in /home/josephj/www/static/platform/.git/ remote: Counting objects: 31, done. remote: Compressing objects: 100% (31/31), done. remote: Total 31 (delta 14), reused 0 (delta 0) Receiving objects: 100% (31/31), 6.06 KiB, done. Resolving deltas: 100% (14/14), done. 
    這時在 /home/josephj/www/ 會產生一個 .gitmodules 記錄你的 Submodule 資訊。該 git 的相關檔案也都會在此時被拉下來
  • 用 git status 看一下:
    $ git status # On branch master # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # new file: .gitmodules # new file: static/platform # 
    會發現它只列出 submodule 目錄而非所有底下檔案,parent git 實際上也只會記錄 submodule 的 commit id 以供未來做比對用。這裡一個很重要的點是大家必須理解的:parent git 與 submodule git 的關連性(被掛入的目錄、repository 位置)記錄在 .gitmodules 中,而版本控制則是靠 parent git 記住 submodule git 的 commit id。
  • 先 commit 一下:
    $ git add .gitmodules static/platform git commit -m "Add submodule into version control";
  • 但是你還必須做 init 的動作,你的 .git/config 才會有對應 submodule 的資訊。
    $ git submodule init 

更新已安裝的 Submodule

當初我第一次新增一個 Submodule 後,以為未來它都會像 SVN External 一樣、在我 git pull 的時候自動更新。但實際情況是你必須手動處理才能更新 Submodule
  1. 進入該目錄 Subomdule 目錄: $ cd static/platform
  2. 向來源的 master branch 做 git pull 的動作(這裡的 git pull 不會更新你 parent git 的檔案) $ git pull origin master
  3. 若 submodule 有更新的檔案,你可以到 parent git 觀看一下情況:
    $ cd ../../ $ git status # Not currently on any branch. # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: static/platform (new commits) # no changes added to commit (use "git add" and/or "git commit -a")
    與第一次 git submodule add 相同,submodule 更新的檔案並不會在 git status 中要求你 commit 喔!
  4. 我們前面提到,submodule 的版本控制在於 submodule git 的 commit id,上面看到 static/platform 有 new commit。表示你既然把新的內容 pull 回來、應該要更新 submodule 的 commit id 到你的 git 中:
    $ git add static/platform $ git commit -m "static/platform submodule updated"
    如此一來,新的 submodule commit id 就被你的 repositiory 給記錄下來囉!

團隊使用 Submodule

在一個多人的軟體開發團隊中,通常還是會有 Centralized Git Repositiory,像我們公司就採用了 gitosis 的解決方案。而像上述更新 Submodule 的情形,通常只有一兩個負責架構的人來做(大多是一開始把東西掛進來的人)、其他人只是單純使用者的角色,並不需要負責更新的工作
  1. 像上面我增加了一個 Submodule,對於團隊其他人來說,他們在下一次的 git pull 會看到以下的狀況:
    $ git status # On branch develop # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: static/platform (new commits) # no changes added to commit (use "git add" and/or "git commit -a")
    這表示其他人也會拿到 .gitmodules 的設定,但他必須使用 git submodule init 將新的 Submodule 註冊到自己的 .git/config、未來才能使用。
    $ git submodule init Submodule 'static/platform' (http://github.com/josephj/javascript-platform-yui.git) registered for path 'static/platform'
  2. 接著其他人使用 git submodule update 把該 Submodule 的內容全部拉下來!
    $ git submodule update Cloning into static/platform... remote: Counting objects: 34, done. remote: Compressing objects: 100% (34/34), done. remote: Total 34 (delta 15), reused 0 (delta 0) Unpacking objects: 100% (34/34), done. Submodule path 'static/platform': checked out '117c5b3c5a195deac2e53aa118b78ef3f01ae371' 

使用時機

簡單整理一下:
  • git submodule init: 在 .gitmodules 第一次被其他人建立或有新增內容的時候,用 git submodule init 更新你的 .git/config、設定目錄與增加 submodule 的 remote URL
  • git submodule update: 在 init 完有新的 submodule commit id 後就可以做了,會把所有相關檔案拉下來。若其他人更新 submodule 造成你拿到新的 commit id 時,你可以直接用 git submodule update 做更新即可、不需要做任何 add 或 commit 的動作!
可以想見,其他成員使用 git submodule update 的情況會遠比 git submodule init 多很多。

修改 Submodule 的內容

有時自己也是 Submodule 的 Owner,碰到要改 Code 時,要我切回原本的此 Git 開發位置有點麻煩… 不如就直接改被當成 Submodule 掛進來的原始碼吧
  1. 到 submodule 目錄去做些修改:
    $ cd static/platform $ vim README # 做些修改 
  2. 接著就是常見的 git add , git commit, git push
    $ git add README $ git commit -m "Add comments" $ git push 
  3. push 完回到根目錄git status 看一下!會看到
    $ git status # On branch master # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: static/platform # no changes added to commit (use "git add" and/or "git commit -a")
  4. 這裡也需要再做一次 Commit 喔!
    $ git add static/platform $ git commit -m 'Submodule updated' $ git push 
這裡有一點非常需要注意,因為 Submodule 的更新只記錄 commit id,所以你必須先在 submodule 內做 commit、push 後、再到 parent git 做 push,不然會出現版本錯亂的問題,別人跟你 submodule 的內容將會不一致。

如何移除 Submodule

這點也非常地不直覺,不是想像中 git submodule remove [欲移除的目錄] 這麼簡單…
  1. 先砍掉目錄:
    $ git rm --cached [欲移除的目錄] $ rm -rf [欲移除的目錄]
  2. 再修改 .gitmodules
    $ vim .gitmodules
    將相關內容移除
  3. 再修改 .git/config
    $ vim .git/config
    將相關內容移除
  4. 最後再 commit,改變整個 Repository。
    $ git add .gitmodules $ git commit -m "Remove a submodule" 
  5. 安全起見再做個 sync:
    $ git submodule sync

結語

我們公司目前主要將 Submodule 運用在與外包公司的合作上,因為彼此 Engineering 團隊負責的專案項目雖不同,但有部分的開發會需要在我們的結構下開目錄,我們也不希望他們改到我們的程式,此時 Git Submodule 提供了非常好的分工效果:把他們開發好的東西掛進來、更新即可。另有一點很重要的是, Git Submodule 內還可以將其他的 Submodule 給掛進來,形成一個巢狀式的結構,彈性非常地大。我們只要抓他們的大 Git 當 Submodule,下面怎麼掛就由外包公司決定。 整篇文章看下來,會發現 git submodule 的操作有許多需要注意的地方,像是更新、修改、刪除都要遵循一定的程序,不然你 PUSH 回 Central Repository 時,別人 PULL 下來的 Submodule 可能並不會更新,就會產生混亂了 Orz… 暇不掩瑜,Git Submodule 還是一個強大且團隊開發上非常重要的功能,就盡量使用前先搞懂、小心使用囉 ;)

10 Cool Premium jQuery Countdown Scripts

10 Cool Premium jQuery Countdown Scripts

Today’s post is a collection of 10 cool “premium” jQuery countdown scripts that you’d definitely find useful for your webpages at some point in time. Enjoy.

1. 5sec Maintenance Mode

6 beautiful, funny templates to make your visitors less angry while you’re offline.

5sec Maintenance Mode Source Demo

2. Premium Coming Soon – WordPress Plugin

New, modern, user friendly countdown page that lets your visitors know when you will launch your website. It has a custom countdown counter and the possibility to create an endless number of new themes as you please.

Premium Coming Soon Source Demo

3. Coming Soon Landing Page

JavaScript under construction website counter!

Coming Soon Landing Page Source Demo

4. fresh Parallax Under Construction Countdown

fresh Parallax Under Construction upgrades your “Coming Soon” page with a dynamic 3D cloudy sky with your logo or item of choice in focus.

fresh Parallax Under Construction Source Demo

5. FlipTimer

FlipTimer 1.2 with 8 color themes ready-made and a beautiful template with working contact form included.

FlipTimer Source Demo

6. Fancy Countdown – jQuery Plugin

It is a highly customizable jQuery plugin that lets you create an outstanding countdown. It´s very easy to use. You can set an own target date with a timezone. The plugin comes with an extensive API.

Fancy Countdown Source Demo

7. Countdown / Construction Page

Easy adaptable countdown, under construction – page. Including manual for easy set-up.

Countdown / Construction Page Source Demo

8. JavaScript Animated Counter

Simple, animated JavaScript counter, which will allow you to present rapidly increased or decreased values, such as number of registered users, total income etc.

JavaScript Animated Counter Source Demo

9. jsCountdown

Included are 14 different skins to choose from and a template file (png format) to make your own.

jsCountdown Source Demo

10. Live Broadcast Countdown Module

Nice jQuery based countdown timer. Header text depending on countdown stateus (counting down or finished). A lot of options available.

Live Broadcast Countdown Source Demo

安装GitLab

安装GitLab

一、准备工作 根据GitLab的官方文档要求,安装GitLab需要以下软件: ruby 1.9.2 sqlite ubuntu/debian pygments lib – sudo pip install pygments gitolite 因此在安装GitLab之前需要做一些准备工作。 1、设置安装环境(安装一些必要软件) sudo apt-get update sudo apt-get dist-upgrade -y sudo apt-get install git-core openssh-server sendmail curl gcc libxml2-dev libxslt-dev sqlite3 libsqlite3-dev libcurl4-openssl-dev libreadline-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev python-setuptools 安装VMWare Tools(这是在虚拟机环境下需要安装的,如果不是的可忽略) sudo apt-get update -y sudo apt-get dist-upgrade -y sudo apt-get install dkms build-essential gcc linux-headers-$(uname -r) -y sudo mkdir -p /media/cdrom sudo mount /dev/cdrom /media/cdrom cp /media/cdrom/VM /tmp sudo umount /media/cdrom cd /tmp tar -xzvf VMware*.gz cd vmware-tools-distrib/ sudo ./vmware-install.pl -d sudo apt-get autoremove -y sudo shutdown -r now 上面关于虚拟机的部分是摘抄官网的,因为没环境测试,所以也只是原样照搬了。:) 2、设置专门的帐号 接下来我们需要创建一个专门的gitlabhq用户帐号来运行程序,这个帐户需要设置密码,因为需要将它加入到admin组来运行sudo: sudo useradd -s /bin/bash -m -G admin gitlabhq sudo passwd gitlabhq 现在使用gitlabhq用户帐号登录机器: ssh gitlabhq@localhost 3、配置git全局变量并生成SSH密钥 git config –global user.email “admin@local.host” git config –global user.name “GitLabHQ Admin User” 由于gitlabhq用户稍后要使用SSH密钥访问稍后创建git用户帐号,执行git命令,所以需要生成gitlabhq用户的SSH密钥: ssh-keygen -t rsa 注意:在出现提示询问文件保存位置时直接回车,在要求输入和确认passphrase时也按回车。 4、安装Ruby 1.9.2、RubyGem和Rails Ubuntu 11.10中的Ruby包,其版本是1.8的,所以需要安装包ruby1.9.2。由于在Ubuntu 11.10中的Ruby1.9.1包中ruby版本实际上是Ruby1.9.2,之所以包名为Ruby1.9.1是因为该版本为1.9.1的“库兼容版本”,所以可以直接安装包Ruby1.9.1即可,然后更新rubygem并安装rails。 sudo apt-get install ruby1.9.1-full sudo update-alternatives –config ruby sudo update-alternatives –config gem sudo gem install rails 注意两点:1)、02-03行命令是在安装了其他ruby版本包时使用;2)、如果在安装rails时出现“RubyGems will revert to legacy indexes degrading performance.”之类的错误时,修改~/.gemrc文件后重试(有时要试多次才进行安装,一般来说都会3-6次之间,下面的bundle命令也是如此,不知道是不是伟大的墙在起作用,看你的运气了!): vi ~/.gemrc — :backtrace: false :benchmark: false :bulk_threshold: 1000 :sources: – http://gems.rubyforge.org/http://gems.github.com/http://gems.rubyonrails.org/ :update_sources: true :verbose: true 5、安装和设置Gitolite Gitolite 是一款 Perl 语言开发的 Git 服务管理工具,通过公钥对用户进行认证,并能够通过配置文件对写操作进行基于分支和路径的的精细授权,它是采用 SSH 协议并且使用 SSH 公钥认证的。Gitolite开始于 2009年8月,其作者当时是受到了 Gitosis 的启发,开发了这款功能更为强大和易于安装的软件。对于Gitolite的命名,作者原意是 Gitosis 和 lite 的组合,不过因为 Gitolite 的功能越来越强大,已经超越了 Gitosis,因此作者笑称 Gitolite 可以看作是 Github-lite —— 轻量级的 Github。 安装Gitolite也十分简单,首先添加git用户帐号并将其加入git组: sudo adduser \ –system \ –shell /bin/sh \ –gecos ‘git version control’ \ –group \ –disabled-password \ –home /home/git \ git sudo usermod -a -G git eval whoami 然后将生成的gitlabhq用户的公钥拷到git用户目录中: sudo cp ~/.ssh/id_rsa.pub /home/git/rails.pub 接下来以git用户的名义将gitolite源文件下载的git用户家目录中: sudo -u git -H git clone git://github.com/gitlabhq/gitolite ~git/gitolite 再以git用户的名义安装gitolite sudo -u git -H /home/git/gitolite/src/gl-system-install 在这里该命令会提示关于目录的警告信息,不用理会。直接运行下列命令: sudo -u git -H sh -c “PATH=/home/git/bin:$PATH; gl-setup ~/rails.pub” 在这里将会出现vim文本编辑器的编辑界面,请将其中的REPO_UMASK=0077改为REPO_UMASK=0007,然后保存退出(退出编辑状态ESC,然后使用:x)。关于如何在vim中编辑这里就不做说明了,我偷个懒,反正有谷歌和百度。:) 最后设置库目录的权限: sudo chmod -R g+rwX ~git/repositories/ sudo chown -R git:git ~git/repositories/ OK,设置完了之后,重新进入一次gitlabhq用户,以使gitlabhq用户生效: exit ssh gitlabhq@localhost 二、安装和设置GitLab 1、安装GitLab cd ~ git clone git://github.com/gitlabhq/gitlabhq.git ~/gitlabhq cd gitlabhq sudo easy_install pygments sudo gem install bundler sudo gem install linecache19 — –with-ruby-include=/usr/include/ruby-1.9.1/ruby/ bundle install –without development test 注意:linecache19的安装是必须要指定with-ruby-include参数的,否则将会在后面的bundle install中出错! 2、设置数据库 bundle exec rake db:setup RAILS_ENV=production bundle exec rake db:seed_fu RAILS_ENV=production 注意:运行01行的rake db:setup语句时,如果出现“unititialized constant Rake::DSL”,则需要在GitLab根目录中的Rakefile文件中添加以下语句(参见http://stackoverflow.com /questions/6268518/uninitialized-constant-rakedsl-in-ruby-gem)来解决,如未出现上述出错信息,可忽略: require ‘rake/dsl_definition’ require ‘rake’ 3、配置GitLab 编辑GitLab的配置程序: vi ~gitlabhq/gitlabhq/config/gitlab.yml 将下列内容 git_host: system: gitolite admin_uri: git@localhost:gitolite-admin base_path: /home/git/repositories/ host: gitlab git_user: git

port: 22

修改为: git_host: system: gitolite admin_uri: git@localhost:gitolite-admin base_path: /home/git/repositories/ host: gitlabhq.your.domain git_user: git

port: 22

其中03和05行中的gitlabhq.your.domain是服务器的域名。 启动服务 cd ~gitlabhq/gitlabhq bundle exec rails s -e production 三、测试服务 如果一切OK的话,就可以在浏览器上输入:http://server.ip:3000/ 来测试该服务了,使用以下信息登录: Email: admin@local.host Password: 5iveL!fe 接下来您可以在admin中创建一个新的用户,注意该用户在创建时要花费一段时间,请耐心等待。在该用户生成成功后,您需要按照前面的方法在客户机上生成该用户的密钥(Windows下可以使用Git for Windows中的Git Bash来代替): ssh-keygen -t rsa -C “your_email@youremail.com” 然后用新用户登录,点击GitLab中My profile>Keys>Add new按钮,将生成的SSH公钥贴到弹出对话框的Key中,Title可随便填,我一般是使用用户机器名这种格式,然后点击Save按钮。 在保存用户公钥之后,就可测试是否可以通过公钥来访问服务器上的git用户,执行git命令: ssh -T git@gitlabhq.your.domain 其中,gitlabhq.your.domain是服务器的域名。如果出现”Agent admitted failure to sign using the key”错误,并提示输入git用户密码,那么请在客户机上使用以下命令将用户私钥加进来 (根据个人的密匙命名不同更改 id_rsa): ssh-add ~/.ssh/id_rsa ssh -T git@gitlabhq.your.domain hello your_email_youremail_com_1324608633, this is gitolite v2.2-11-g8c4d1aa running on git 1.7.5.4 the gitolite config gives you the following access: @R @W_ testing 再次访问git,如出现类似02行信息时,则表明设置成功。 四、安裝和配置 Nginx和Passenger 1、卸载Apache2 sudo apt-get autoremove apache2 sudo dpkg –purge apache2 2、安装Nginx和Passenger模块 sudo gem install passenger sudo passenger-install-ngnix-module 注意:02行语句会检查编译Ngnix和Passenger模块所需要的工具,然后询问你是否有Ngnix的源码,如果没有的话,就选1,会自动下载,如果有的话,就选2,并告之源码所在位置。在这里选择1。 3、创建运行Nginx服务的用户 sudo adduser –system –no-create-home –disabled-login –disabled-password –group nginx 4、将Nginx设置开机启动脚本 wget -O init-deb.sh http://library.linode.com/assets/660-init-deb.sh sudo mv init-deb.sh /etc/init.d/nginx sudo chmod +x /etc/init.d/nginx sudo /usr/sbin/update-rc.d -f nginx defaults 5、将Nginx设置为GitLab的服务器 sudo vi /opt/nginx/conf/nginx.conf

user gitlabhq staff;

server { listen 80; server_name gitlabhq.your.domain; root /home/gitlabhq/gitlabhq/public; passenger_enabled on; }

其中,07行的gitlab.yourdomain.com要改为你的域名。 6、启动Nginx sudo /etc/init.d/nginx start 五、测试服务 在浏览器中输入http://gitlab.yourdomain.com/%E6%9D%A5%E6%B5%8B%E8%AF%95GitLab%E8%83%BD%E6%98%AF%E5%90%A6%E6%AD%A3%E5%B8%B8%E5%B7%A5%E4%BD%9C%E3%80%82%E5%A6%82%E6%9E%9C%E4%B8%80%E5%88%87%E6%AD%A3%E5%B8%B8%E7%9A%84%E8%AF%9D%EF%BC%8C%E5%B0%B1%E5%8F%AF%E4%BB%A5%E6%89%93%E5%AE%8C%E6%94%B6%E5%8A%9F%E4%BA%86%EF%BC%81

What Are the Options for Storing Hierarchical 分层 Data in a Relational Database?

What are the Options for Storing Hierarchical 分层 Data in a Relational Database?

Generally speaking you’re making a decision between fast read times (e.g. nested set) or fast write times (adjacency list). Usually you end up with a combination of the options below that best fit your needs. The following provides some in depth reading:

Options

Ones I am aware of and general features:

  1. Adjacency List:
    • Columns: ID, ParentID
    • Easy to implement.
    • Cheap node moves, inserts, and deletes.
    • Expensive to find level (can store as a computed column), ancestry & descendants (Bridge Hierarchy combined with level column can solve), path (Lineage Column can solve).
    • Use Common Table Expressions in those databases that support them to traverse.
  2. Nested Set (a.k.a Modified Preorder Tree Traversal)
    • First described by Joe Celko - covered in depth in his book Trees and Hierarchies in SQL for Smarties
    • Columns: Left, Right
    • Cheap level, ancestry, descendants
    • Compared to Adjacency List, moves, inserts, deletes more expensive.
    • Requires a specific sort order (e.g. created). So sorting all descendants in a different order requires additional work.
  3. Nested Intervals
    • Combination of Nested Sets and Materialized Path where left/right columns are floating point decimals instead of integers and encode the path information. In the later development of this idea nested intervals gave rise to matrix encoding.
  4. Bridge Table (a.k.a. Closure Table: some good ideas about how to use triggers for maintaining this approach)
    • Columns: ancestor, descendant
    • Stands apart from table it describes.
    • Can include some nodes in more than one hierarchy.
    • Cheap ancestry and descendants (albeit not in what order)
    • For complete knowledge of a hierarchy needs to be combined with another option.
  5. Flat Table
    • A modification of the Adjacency List that adds a Level and Rank (e.g. ordering) column to each record.
    • Expensive move and delete
    • Cheap ancestry and descendants
    • Good Use: threaded discussion - forums / blog comments
  6. Lineage Column (a.k.a. Materialized Path, Path Enumeration)
    • Column: lineage (e.g. /parent/child/grandchild/etc…)
    • Limit to how deep the hierarchy can be.
    • Descendants cheap (e.g. LEFT(lineage, #) = '/enumerated/path')
    • Ancestry tricky (database specific queries)

Database Specific Notes

MySQL

Oracle

PostgreSQL

SQL Server

  • General summary
  • 2008 offers HierarchyId data type appears to help with Lineage Column approach and expand the depth that can be represented.

Some articles from my blog on the subject:

Gedit Keyboard Shortcuts

Gedit Keyboard Shortcuts

Shortcut keys enable you to perform tasks more quickly than if you use a mouse. The following tables list all of Gedit’s shortcut keys. These are in the Gedit user manualas of version 2.18.

Tabs

Shortcut Key Command
Ctrl + Alt + PageUp Switches to the next tab to the left.
Ctrl + Alt + PageDown Switches to the next tab to the right.
Ctrl + W Close tab.
Ctrl + Shift + L Save all tabs.
Ctrl + Shift + W Close all tabs.
Alt + n Jump to nth tab.

Files

Shortcut Key Command
Ctrl + N Create a new document.
Ctrl + O Open a document.
Ctrl + L Open a location.
Ctrl + S Save the current document to disk.
Ctrl + Shift + S Save the current document with a new filename.
Ctrl + P Print the current document.
Ctrl + Shift + P Print preview.
Ctrl + W Close the current document.
Ctrl + Q Quit Gedit.

Edit

Shortcut Key Command
Ctrl + Z Undo the last action.
Ctrl + Shift + Z Redo the last undone action .
Ctrl + X Cut the selected text or region and place it on the clipboard.
Ctrl + C Copy the selected text or region onto the clipboard.
Ctrl + V Paste the contents of the clipboard.
Ctrl + A Select all.

Edit (from GTKTextView)

Shortcut Key Command
Ctrl + D Delete the line.
Ctrl + Left Move the cursor to the beginning of the word or previous word if it’s already in the beginning of the current one.
Ctrl + Right Move the cursor to the end of the word or next word if it’s already in the end of the current one.

Panes

Shortcut Key Command
F9 Show/hide the side pane.
Ctrl + F9 Show/hide the bottom pane.
Shortcut Key Command
Ctrl + F Find a string.
Ctrl + G Find the next instance of the string.
Ctrl + Shift + G Find the previous instance of the string.
Ctrl + K Interactive search.
Ctrl + H Search and replace.
Ctrl + Shift + K Clear highlight.
Ctrl + I Goto line.

Tools

Shortcut Key Command
F7 Check spelling (with plugin).
Alt + F12 Remove trailing spaces (with plugin).
Ctrl + T Indent (with plugin).
Ctrl + Shift + T Remove Indent (with plugin).
F8 Run “make” in current directory (with plugin).
Ctrl + Shift + D Directory listing (with plugin).

Help

Shortcut Key Command
F1 Load Gedit’s online help document.