Files
wahyd4.github.com/index.html
T

2287 lines
80 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html class="theme-next gemini use-motion" lang="zh-Hans">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />
<link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />
<link href="/css/main.css?v=5.1.2" rel="stylesheet" type="text/css" />
<meta name="keywords" content="Go, JavaScript, Ruby on Rails, Java, Git, Docker, CI, CD, HTML5, 创新, 拍照, 创业, Cordova" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.2" />
<meta name="description" content="Go, JavaScript, Ruby on Rails, Java, Git, Docker, CI, CD, HTML5, 创新, 拍照, 创业, Cordova">
<meta property="og:type" content="website">
<meta property="og:title" content="大染志">
<meta property="og:url" content="http://toozhao.com/index.html">
<meta property="og:site_name" content="大染志">
<meta property="og:description" content="Go, JavaScript, Ruby on Rails, Java, Git, Docker, CI, CD, HTML5, 创新, 拍照, 创业, Cordova">
<meta property="og:locale" content="zh-Hans">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="大染志">
<meta name="twitter:description" content="Go, JavaScript, Ruby on Rails, Java, Git, Docker, CI, CD, HTML5, 创新, 拍照, 创业, Cordova">
<script type="text/javascript" id="hexo.configurations">
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Gemini',
version: '5.1.2',
sidebar: {"position":"left","display":"post","offset":12,"offset_float":12,"b2t":false,"scrollpercent":false,"onmobile":false},
fancybox: true,
tabs: true,
motion: true,
duoshuo: {
userId: '0',
author: '博主'
},
algolia: {
applicationID: '',
apiKey: '',
indexName: '',
hits: {"per_page":10},
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
}
};
</script>
<link rel="canonical" href="http://toozhao.com/"/>
<title>大染志</title>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-5243064-16', 'auto');
ga('send', 'pageview');
</script>
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">
<div class="container sidebar-position-left
page-home
">
<div class="headband"></div>
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-wrapper">
<div class="site-meta ">
<div class="custom-logo-site-title">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<span class="site-title">大染志</span>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<p class="site-subtitle">想要玩得很 High 的程序员</p>
</div>
<div class="site-nav-toggle">
<button>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
</button>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section">
<i class="menu-item-icon fa fa-fw fa-home"></i> <br />
首页
</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section">
<i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
归档
</a>
</li>
<li class="menu-item menu-item-about">
<a href="/about" rel="section">
<i class="menu-item-icon fa fa-fw fa-user"></i> <br />
关于
</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories/" rel="section">
<i class="menu-item-icon fa fa-fw fa-th"></i> <br />
分类
</a>
</li>
</ul>
</nav>
</div>
</header>
<main id="main" class="main">
<div class="main-inner">
<div class="content-wrap">
<div id="content" class="content">
<section id="posts" class="posts-expand">
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2016/10/17/easiest-way-to-use-go/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/10/17/easiest-way-to-use-go/" itemprop="url">开发Go项目最简单的方式 — 一个基于Docker的go 工具</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2016-10-17T11:30:00+08:00">
2016-10-17
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2016-10-17T11:15:21+08:00">
2016-10-17
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/docker/" itemprop="url" rel="index">
<span itemprop="name">docker</span>
</a>
</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/docker/go/" itemprop="url" rel="index">
<span itemprop="name">go</span>
</a>
</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/docker/go/翻译/" itemprop="url" rel="index">
<span itemprop="name">翻译</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>当我尝试开发一个在 <a href="[http://www.iron.io/worker]">IronWorkerr</a> 上运行的非常简单的程序的时候,我发现目前为止没有一个工具可以让人在几分钟之内运行一段 Go 的示例代码。但在其他语言里面这是可以很容易做到的, 因为他们不像 Go 一样需要设置 GOPATH环境变量,遵守一个特定的代码目录结构,而且他们通常还有更简单的依赖管理工具。</p>
<h3 id="有什么更好的方式吗?"><a href="#有什么更好的方式吗?" class="headerlink" title="有什么更好的方式吗?"></a>有什么更好的方式吗?</h3><p>我最近想了很多,也写了很过关于 Docker 的文章, 并尝试在所有能使用 Docker 的情境下都坚持使用 Docker(是的,我是 Docker 的超级粉丝)。大部分原因是因为在 <a href="[http://www.iron.io/]">Iron.io</a> ,我们从事 Docker 的相关工作。我们运行了很多 Docker 容器,<a href="http://www.iron.io/blog/2014/10/docker-in-production-what-weve-learned.html" target="_blank" rel="external">真的很多</a>。在这期间,我已经意识到 Docker 的强大与疯狂之处。相信我,这不只是炒作。</p>
<p>我们向用户展示如何使用 Docker 容器构建和测试他们的 Go 语言程序已经有一段时间了,但始终有一个痛点,让我们如鲠在喉。那便是用户需要将代码放到特定的目录, 配置 GOPATH 环境变量,使用一个第三方工具如 godep 来 加载和代理依赖(注意通常这些依赖和你的代码一样,也需要被版本控制管理),有序的加载相关目录等等。这些当然可以完成,但是总是让人觉得不够爽。</p>
<p>现在,这个流程变得更好些了。</p>
<h3 id="介绍下这个基于-Docker-的-Go-工具"><a href="#介绍下这个基于-Docker-的-Go-工具" class="headerlink" title="介绍下这个基于 Docker 的 Go 工具"></a>介绍下这个基于 Docker 的 Go 工具</h3><p>我创建了一个基于 Docker 的 go 工具—— <a href="[https://hub.docker.com/r/treeder/go/]">“treeder/go”</a> ,他让 Go 语言开发变得超级简单。 你唯一需要安装的只有 Docker。 下面是一些它的一些功能和好处: </p>
<ul>
<li>你不需要安装 Go</li>
<li>你不需要安装这些相关的工具</li>
<li>你不需要配置 GOPATH 环境变量</li>
<li>你不需要将你的代码放到特定的目录(如: /src/github.com/user/hello)或者 Go 的安装目录, 你可以任意放置你的代码。</li>
<li>不需要重写代码里面依赖导入目录就可以加载相应依赖</li>
<li>代码交叉编译</li>
<li>代码静态编译</li>
<li>将代码打包成 Docker 镜像(一个命令即可搞定,然后你将得到一个包含你的代码的镜像)</li>
<li>构建远端 git 仓库的代码</li>
</ul>
<h3 id="演示"><a href="#演示" class="headerlink" title="演示"></a>演示</h3><h5 id="基础部分"><a href="#基础部分" class="headerlink" title="基础部分"></a>基础部分</h5><p>让我们先来写个简单的例子,首先复制粘贴下面的代码到一个叫 app.go 的文件,放到任意目录。<br><figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> main</div><div class="line"></div><div class="line"><span class="keyword">import</span> (</div><div class="line"> <span class="string">"fmt"</span></div><div class="line"> <span class="string">"log"</span></div><div class="line"> <span class="string">"net/http"</span></div><div class="line"></div><div class="line"> <span class="string">"github.com/gorilla/mux"</span></div><div class="line">)</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</div><div class="line"> r := mux.NewRouter()</div><div class="line"> r.HandleFunc(<span class="string">"/"</span>, Hello)</div><div class="line"> http.Handle(<span class="string">"/"</span>, r)</div><div class="line"> fmt.Println(<span class="string">"Starting up on 8080"</span>)</div><div class="line"> log.Fatal(http.ListenAndServe(<span class="string">":8080"</span>, <span class="literal">nil</span>))</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">Hello</span><span class="params">(w http.ResponseWriter, req *http.Request)</span></span> &#123;</div><div class="line"> fmt.Fprintln(w, <span class="string">"Hello world!"</span>)</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>注意到这段代码有第三方依赖了吗? 让我们来代理(vendor) 依赖:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">docker run --rm -v <span class="variable">$PWD</span>:/app -w /app treeder/go vendor</div></pre></td></tr></table></figure>
<p>上述命令会把抵赖都放 /vendor 目录下<br>然后我们对代码进行构建:<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">docker run --rm -v <span class="variable">$PWD</span>:/app -w /app treeder/go build</div></pre></td></tr></table></figure></p>
<p>接着,我们来运行代码:<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">docker run --rm -v <span class="variable">$PWD</span>:/app -w /app -p 8080:8080 iron/base ./app</div></pre></td></tr></table></figure></p>
<p>打开浏览器,输入 <a href="[http://localhost:8080]">http://localhost:8080</a>. 哈哈,我们成功的通过 <code>iron/base</code> 这个基础镜像运行了我们的代码。它是一个包含了运行 GO 程序所需的所有东西的很小的镜像。</p>
<p>#####更酷炫的东西</p>
<p>构建一个包含你的代码的可以运行的 Docker 镜像怎么样?<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">docker run --rm -v <span class="variable">$PWD</span>:/app -w /app -v /var/run/docker.sock:/var/run/docker.sock treeder/go image username/myapp:latest</div></pre></td></tr></table></figure></p>
<p>现在通过你的新镜像来运行代码吧:<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">docker run --rm -p 8080:8080 username/myapp</div></pre></td></tr></table></figure></p>
<p>再次打开 <a href="[http://localhost:8080]">http://localhost:8080</a>,哈哈,现在流程是不是更好了。 这个镜像非常小。你可以通过输入 <code>docker images</code> 来查看这个镜像到底有好大,大概在12M左右吧。</p>
<p>或者你也可以下载和构建一个远程的代码仓库:<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">docker run --rm -v <span class="variable">$PWD</span>:/app -w /app treeder/go remote https://github.com/treeder/hello-app.go.git</div></pre></td></tr></table></figure></p>
<p>最后你将得到一个包含这个远程代码仓库的代码的镜像。</p>
<p>###结论</p>
<p><a href="[https://medium.com/iron-io-blog/why-and-how-to-use-docker-for-development-a156c1de3b24]">将 Docker 运用于开发</a>再次胜利了,如果你之前开发过 Go 项目,你应该会感谢这个工具带来的简单和简洁。不过它还仅仅是个实验阶段的工具,没有包含太多的其他工具链。不过,就我知道的而言,这应该是最简单的 Go 上手方式了。通过这个工具,仅仅告诉其他人一个代码仓库链接,他们就可以克隆,构建,运行代码而不需要任何初始化流程仅仅只需要 Docker。</p>
<p>完整的文档和项目源代码请浏览: <a href="https://github.com/treeder/go" target="_blank" rel="external">https://github.com/treeder/go</a></p>
<p>请不要吝啬你的任何反馈,创建一个 <a href="[https://github.com/treeder/go/issues]">Github issue</a> 或者评论吧。</p>
<p><code>更新: 我做了一个更大更好的工具:https://github.com/treeder/devo</code></p>
<p>翻译自:<a href="https://medium.com/iron-io-blog/the-easiest-way-to-develop-with-go-introducing-a-docker-based-go-tool-c456238507d6" target="_blank" rel="external">https://medium.com/iron-io-blog/the-easiest-way-to-develop-with-go-introducing-a-docker-based-go-tool-c456238507d6</a></p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2015/03/21/active-model-serializers/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2015/03/21/active-model-serializers/" itemprop="url">在Rails中使用 active_model_serializers 构建json response</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2015-03-21T10:35:43+08:00">
2015-03-21
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2015-03-21T12:00:16+08:00">
2015-03-21
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/ruby/" itemprop="url" rel="index">
<span itemprop="name">ruby</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>Rails 本身提供很不错的json response功能,可以很方便的将model对象自动转换为json数据。如果我们期望返回的结果很简单也可以构建一个简单的hash,自行编辑你希望的key和value,由Rails 来帮你生成json。那如果是介于两者之间的情况呢?</p>
<ul>
<li>我希望将我的model以json的形式返回,但是我并不希望将所有的字段返回。</li>
<li>我希望将我的model中部分属性进行稍微的处理和计算后返回,这样客户端可以直接使用某些字段,而不需要将应用自身的逻辑暴露给客户端,如我有个model记录微信支付属性,有个字段是关于微信支付(”trade_status”),它的值有trade_success, “wait_for_payment”,显然我们可以返回给客户端 “支付成功”,”等待支付”更好。传统的做法,我们为了达到这个目的,我们不仅需要将trade_stauts进行构建,还需要将其他参数也重复写出来。</li>
</ul>
<p>ActiveModel::Serializers这个gem 包就可以更好的帮助我们解决上面的痛点,我们只需要对需要返回的属性列举出来,只对需要更改的属性进行计算,其他都不需要了。下面就介绍下它的一些常见用法。</p>
<p>首先安装Gem<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">gem <span class="string">'active_model_serializers'</span></div></pre></td></tr></table></figure></p>
<p>为了可以在我们的rails 项目中使用它,我们还需要在application controller中添加:<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">include</span> ActionController::Serialization</div></pre></td></tr></table></figure></p>
<p>active_model_serializers的使用就是在你是需要返回json的地方,为你的数据创建serializer,你的对象就能通过serializer变成希望的结果。这里假设我有一个User用户对象,User的的大致结构:<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span></span></div><div class="line"> field <span class="symbol">:nick_name</span>, <span class="symbol">type:</span> String</div><div class="line"> field <span class="symbol">:email</span>, <span class="symbol">type:</span> String</div><div class="line"> field <span class="symbol">:age</span>, <span class="symbol">type:</span> Integer</div><div class="line"> field <span class="symbol">:password</span>, <span class="symbol">type:</span>String</div><div class="line"> <span class="comment"># 等等更多属性。。。</span></div><div class="line"><span class="keyword">end</span></div></pre></td></tr></table></figure></p>
<p>我现在有个UserController,需要以JSON的形式返回用户的基本信息: 昵称,邮箱,是否成年(大于等于18岁算成年),接下来在app 目录下创建serializers 目录,并创建class UserSerializer对象,继承自 ActiveModel::Serializer, 然后我们的serializer就应该是这样:<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">UserSerializer</span> &lt; ActiveModel::Serializer</span></div><div class="line"> attributes <span class="symbol">:nick_name</span>, <span class="symbol">:email</span>, <span class="symbol">:if_adult</span></div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">def</span> <span class="title">if_adult</span></span></div><div class="line"> object.age &gt; <span class="number">18</span> <span class="comment">#object 就是需要被序列化的对象</span></div><div class="line"> <span class="keyword">end</span></div><div class="line"><span class="keyword">end</span></div></pre></td></tr></table></figure></p>
<p>在serializer中,我们只需要将我们需要的属性通过attributes 的形式列出来,如果model没有的属性,我们需要自行实现该方法。<br>我们也可以覆盖属性,如上的例子,我们也可以将if_adult 改成age,同样我们需要有:<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">age</span></span></div><div class="line"> object.age &gt; <span class="number">18</span></div><div class="line"><span class="keyword">end</span></div></pre></td></tr></table></figure></p>
<p>接下来完成我们的最后一步,在controller中使用serializer</p>
<figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">UserController</span> &lt; ApplicationController</span></div><div class="line"> <span class="function"><span class="keyword">def</span> <span class="title">show</span></span></div><div class="line"> <span class="comment">#假设 <span class="doctag">@user</span> 是我们经过查询后得到的对象</span></div><div class="line"> render <span class="symbol">json:</span> @user, <span class="symbol">serializer:</span> UserSerializer</div><div class="line"> <span class="keyword">end</span></div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">def</span> <span class="title">index</span></span></div><div class="line"> <span class="comment">#假设 <span class="doctag">@users</span> 是我们经过查询后得到的对象</span></div><div class="line"> render <span class="symbol">json:</span> @user, <span class="symbol">each_serializer:</span> UserSerializer</div><div class="line"> <span class="keyword">end</span></div><div class="line"><span class="keyword">end</span></div></pre></td></tr></table></figure>
<p>我们我们希望对一个数组对象进行序列化,我们则需要使用each_serializer,使用该属性后,你的返回结果将变成对象,数组则包裹下对象之下。本例则类似于<br><figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">users: [</div><div class="line"> &#123;&#125;,</div><div class="line"> &#123;&#125;</div><div class="line">]</div></pre></td></tr></table></figure></p>
<p>这里的”users”这是json的根属性, serializer支持用户自定义根属性,<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">render <span class="symbol">json:</span> @user, <span class="symbol">serializer:</span> UserSerializer, <span class="symbol">root:</span> <span class="string">'customer'</span></div></pre></td></tr></table></figure></p>
<p>我非常喜欢active model serializers 的一个属性是,支持在serializer中访问你希望的属性,在rails 中,很多时候我们希望访问current_user对象,获取当前登录用户的相关信息。那serializer 则可以很好的做的这一点,在active model serializers 中有 serialization_scope 这样一个方法,在application controller 中声明此方法,传入你希望的参数,便可以在serializer class 中自由访问该对象。解决了serializer 与其他对象交互的问题。<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">serialization_scope <span class="symbol">:current_user</span></div></pre></td></tr></table></figure></p>
<p>在serializer中, scope 对象便是注入的 current_user对象<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">scope.email</div></pre></td></tr></table></figure></p>
<p>此外,active model serializers 支持在返回的json中额外注入meta属性,这样既保留了serializer的简单,模板化,也增添了自由度,使得用户可以自行添加一些额外的属性。</p>
<p>更详细的使用还请参考:<a href="https://github.com/rails-api/active_model_serializers" target="_blank" rel="external">Github</a></p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2014/10/25/some-photos-from-Daocheng-and-Yading/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2014/10/25/some-photos-from-Daocheng-and-Yading/" itemprop="url">稻城、亚丁自驾游之行的一些照片</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2014-10-25T20:36:26+08:00">
2014-10-25
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2014-10-25T21:13:14+08:00">
2014-10-25
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/photos/" itemprop="url" rel="index">
<span itemprop="name">photos</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>上周星期天,我和她开启了我们一周的稻城亚丁自驾游之旅,虽然途中经历过长达5,6个小时大堵车,因二郎山修路弄得烂泥一样的路面,下雪等诸多不太好的情况,但是我们在途中所看到的景美翻了,呼吸到的空气不能再清新,不得不说稻城、亚丁让我们醉了。总得来说非常值得一去,相比九寨沟最美的是水,亚丁则最美的是蓝天、白云、黄叶、雪山。<br>此行我们大致的行程是: </p>
<pre><code>第一天:成都——新都桥(二郎山烂路,因修路堵车5个小时左右)
第二天:新都桥——稻城 (因318国道修路,有30公里土石路)
第三天:稻城——亚丁 (仅100公里,可先在亚丁景区附近或者景区内游玩,或游览俄初山,仅30公里左右)
第四天:亚丁旅游,晚上返回稻城
第五天:稻城——康定
第六天:康定——成都(绕道石棉县,上雅西高速回成都)
</code></pre><p>最后附上我拍的照片几张。</p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0328.jpg" alt="草原"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0342.jpg" alt="晚霞"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0355.jpg" alt="稻城河"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0370.jpg" alt="白桦树林"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0374.jpg" alt="白桦树"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0382.jpg" alt="半山上的寺庙"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0394.jpg" alt="结冰的湖泊"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0419.jpg" alt="亚丁的星空"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0462.jpg" alt="亚丁的一座神山"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0588.jpg" alt="通往远方的栈道"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0589.jpg" alt="与Mac OSX 某张桌面壁纸类似"></p>
<p><img src="http://junv-photos.qiniudn.com/_MG_0645.jpg" alt="不知是野鹿还是羊"></p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2014/10/03/photos-in-Beijing/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2014/10/03/photos-in-Beijing/" itemprop="url">56月在北京的几张照片</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2014-10-03T09:27:44+08:00">
2014-10-03
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2014-10-03T09:37:57+08:00">
2014-10-03
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/photos/" itemprop="url" rel="index">
<span itemprop="name">photos</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p><img src="http://junv-photos.qiniudn.com/DSC00041.jpg" alt="朝阳医院外"><br><img src="http://junv-photos.qiniudn.com/DSC00045.jpg" alt="不知名的花"><br><img src="http://junv-photos.qiniudn.com/DSC00051.jpg" alt="复兴国际"><br><img src="http://junv-photos.qiniudn.com/DSC00066.jpg" alt="HDR云"><br><img src="http://junv-photos.qiniudn.com/DSC00074.jpg" alt="复兴国际门前"></p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2014/08/31/improve-the-load-speed-of-blog/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2014/08/31/improve-the-load-speed-of-blog/" itemprop="url">使用七牛云提升博客加载速度</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2014-08-31T20:26:40+08:00">
2014-08-31
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2015-08-04T11:33:17+08:00">
2015-08-04
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/我说/" itemprop="url" rel="index">
<span itemprop="name">我说</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>由于大家都懂的原因,谷歌被彻底封锁了,连供程序员使用的在线托管的第三方库google apis,和 google web fonts 也不能使用了。<br>这使得本来放在国外的博客变得更慢,关键是如果用了那些库的话,基本上是几分钟都加载不了的节奏。<br>我的博客放在github page上,最近也发现访问也越来越慢,比如JS、css、图片等加载都很慢。然后就有了优化的想法,恰好之前有同事提到他使用过七牛云还不错,速度在国内挺快,而且注册后还有免费的套餐用,而且基本够用。<br>现在使用了之后发现,的确够用,对于我这样一个每天只有几十个人访问的博客而言。简单讲讲我是怎么优化的。</p>
<ul>
<li>去掉不必要的JS、CSS等资源文件,我现在使用的是Hexo,最终的博客都是以预生成的静态HTML文件。在详细观察HTML的结构后发现其实有一些js是不需要的,<br>如fancybox-一款图片插件插件,提供画廊的形式查看当然博客的图片,对我而言嵌在网页里足以;mathx?,一款用于在网页上显示数学公式的js插件,对我是在没必要。</li>
<li>在Chrome 的控制台中发现网页加载图片、和JS奇慢,很多都需要2,3秒才能加载成功。因此我想到了那那些稍大的图片和JS均放到七牛云里面。</li>
<li>替换引用的google 相关资源文件,我的博客里面主要用来google web font的一款字体,因为google 上的字体本身也是开源的,我便把我需要使用的字体存一份在七牛云上,<br>自己在CSS 里面声明一个@fontface即可。(这样做应该没有侵犯版权吧)</li>
<li>使用GZIP 对生成的HTML进行压缩,也可以减小传输时间。 </li>
</ul>
<p>在进行了以上的步骤之后,网页的记载速度有很大提升。之前是ping 通网页以后,通常还需要10秒以上的时间才能及在完,现在大概只需要3秒左右的时间。<br>偶尔依然比较慢,经过查看后发现依然是剩下放在在github 的js,css加载很慢。Anyway, 已经是可以接受的范围了。 </p>
<p>这里不得不赞一下七牛云,在国内的访问速度的确是很话说,因为也曾用过360的一个公共CDN的JS库,加载速度还是会比七牛云慢一截,关键是现在免费的每月10G流量已经够我使用了。<br>最后放一张优化后的加载时间图.<br><img src="http://7narz1.com1.z0.glb.clouddn.com/web-assets.png?imageView2/2/w/1024" alt="加载时间"></p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2014/06/21/my-experience-about-publish-app-to-apple-store/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2014/06/21/my-experience-about-publish-app-to-apple-store/" itemprop="url">发布iPhone应用到Apple Store的经历</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2014-06-21T22:26:40+08:00">
2014-06-21
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2014-07-20T23:58:32+08:00">
2014-07-20
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/apple/" itemprop="url" rel="index">
<span itemprop="name">apple</span>
</a>
</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/apple/我说/" itemprop="url" rel="index">
<span itemprop="name">我说</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>理想是丰满的,现实是骨干的。<br>成功在于高效强有力的执行力。</p>
<p>在尝试发布iPhone应用之前就在网上看过一些资料,也在论坛里面看到其他人发的帖子,都提及发布应用时间比较漫长,可能会被苹果打回进行相关修改后才能继续发布。但是没有想到我的这次发布,期间总共进行了大大小小的4次修改,共花了50天左右的时间。下面就聊聊这次发布过程中的故事吧。</p>
<p>— 需要补充 —</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2014/04/09/develop-web-based-cross-platform-mobile-app/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2014/04/09/develop-web-based-cross-platform-mobile-app/" itemprop="url">Develop web based cross platform mobile app(开发基于Web的跨平台移动应用)</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2014-04-09T16:48:45+08:00">
2014-04-09
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2014-04-09T16:55:42+08:00">
2014-04-09
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/web/" itemprop="url" rel="index">
<span itemprop="name">web</span>
</a>
</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/web/mobile/" itemprop="url" rel="index">
<span itemprop="name">mobile</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>这是我在公司做的一个内部分享的PPT,主要分享的是利用WEB 相关的开发技术开发跨平台的移动应用。</p>
<p>demo 应用可以从 <a href="http://librme.com" target="_blank" rel="external">http://librme.com</a> 找到,此外PPT 中提到的技术有: </p>
<ul>
<li>Angular.js</li>
<li>Node.js</li>
<li>Gulp.js</li>
<li>bower.js</li>
<li>Ionic framework</li>
<li>Cordova / Phonegap</li>
<li>CoffeeScript</li>
</ul>
<p>下面是PPT 资料:</p>
<script async class="speakerdeck-embed" data-id="1c36cc30a1f00131d5c20ec531db4d7f" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2013/11/26/what-do-i-think-of-agile/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2013/11/26/what-do-i-think-of-agile/" itemprop="url">我怎么看敏捷</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2013-11-26T18:51:55+08:00">
2013-11-26
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2013-11-26T20:31:33+08:00">
2013-11-26
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/我说/" itemprop="url" rel="index">
<span itemprop="name">我说</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p><img src="/images/2013/11/agile.jpg" alt="Agile"><br>去年11月份的时候,我进到了ThoughWorks实习,开始了我的TW生涯,从现在除去今年年初由于毕业论文断断续续的10天左右的请假,我已经到ThoughtWorks1年了,现在我想来我聊聊我眼中的敏捷和我对敏捷的看法。它是比较主观的看法。<br>首先,我必须得说敏捷并不是完美无缺的,当然也不是所有行业,所有软件项目都适合使用敏捷来开发和管理的。很明显的一个例子就是,你不能用敏捷来开发NASA的航天飞机的软件系统。从敏捷的理念我们会说,我们让开发航天飞机的起飞系统,然后交付给NASA使用,之后再继续交付降落等其他系统,显示这是行不通的,航天飞机不能在仅仅拥有起飞功能的时候就上天啊。敏捷里强调快速交付,快速响应,及时修复bug,因此我们会允许软件存在潜在少量bug的时候让其上线,使用。这在航天飞行系统里面也是行不通的,因为涉及到人的生命,航天飞行系统应该是不允许任何bug的。 </p>
<blockquote>
<p>但我依然会说,敏捷是一种很好的理念和实践,适合大部分IT企业使用,特别是互联网企业和运行互联网产品的企业使用。</p>
</blockquote>
<p>在现在互联网时代,天下武功唯快不破。采用敏捷的实践,初期开发MVPMinimal Valuable Product)产品,快速上线,根据用户的反馈不断更新、改进自己的产品,开发新的功能,这样周而复始,产品把用户最喜欢,优先级最高的功能永远都放在第一时间开发、上线。根据用户的反馈、统计数据的结果不断调整产品的策略,这样才能立于当今互联网。在我们身边也许Github、 Flickr等都是很好的成功例子。<br>下面是我对于一些是非的意见: </p>
<ul>
<li>结对编程能够明显提升代码的质量,让团队成员对代码的熟悉度大幅提升,但是我不赞成至始至终都是结对编程,应该留时间进行单独编程,这样虽然代码质量也许会有一些下降,但是如果伴以TDD对进行辅佐,是不会下降太多,单独编程有助于让dev独立思考,发挥创造力,很多时候会达到意想不到的结果。另外一点结果编程通常达不到两个dev独立编写代码的效率,就像在《人月神话》中讲到的那样,1一个人如果需要开发一个软件需要100填,那么10个程序员10天肯定不能完成任务的,因为期间还需要算上沟通的成本。 </li>
<li>关于TDD,确有遇到过几次绞尽脑汁也没想明白怎么测试的case。但是我们如果使用 隔离依赖(即mock依赖,stub行为,如使用mockito中的:given().willReturn();或者when().thenReturn()等)的原则来编写测试,绝大多数情况都会变得豁然开朗,就Java而言,遇到静态方法,我们可以通过间接的调用去测试,对于无返回值的方法(void)我们可以采用验证行为的方法去测试(如使用mockito中的verify()函数)。使用TDD的好处是不言而喻的,用测试代码描述你的需求,表达你想要的结果,既保证了质量也不用担心会做出多余的功能。不过在开发自己的小点子、小创意时,我通常选择Rails和Node.js进行开发因此TDD做得并不好,通产只是选择性的对重要的部分进行测试保证。</li>
<li>沟通胜于一切,跟项目中所有的人频繁沟通,在实际项目中有一次是这样的,对于story中一个对于生效时间信息的描述有些模糊,我没有多想久自己认为肯定的全局的生效时间,但是不曾想到,当多个子产品出现时,就不能依赖全局生效时间,因为全局生效时间是其中最大第一个,而不一定是当前所需准确的生效时间,因此这个sotry在最后给BA 检查的时候才发现这个bug,试想最初如果我没有随便假设,而是马上给BA发邮件沟通,问清楚生效时间,也不会出现返工的情况。我个人认为良好、高效的沟通甚至比写好代码优先级更高。 </li>
<li>站会(stand up)既是一种对团队成员工作的可视化,了解彼此的进度等情况,也是锻炼表达能力、增强自信心的好机会。为何这样讲,因为在站会上每个人需要用几句话来概括自己前一天所做的一切,当你讲到你前一天做的一些进步时,团队为你真心叫好,难道不会让你你增强自信心吗?对于站会进行的方式,有团队会选择每个人依次讲解前一天的工作内容;也有人会选择采用按照故事墙的方式来进行,依次对每个列(analysis, ready for dev, in development, test, sign off等)进行浏览等,当讲到自己的那个story时,每个人需要更新自己前一天在这个story上的工作,这样的好处是可以对每个story的情况进行可视化。但是我个人更喜欢前者,这样更加自由,但是目前在工作中基本尝试的都是后者。 </li>
<li>另外一点是尽早集成,这点感触很深,大三的时候在一家公司实习,当时做一个原型系统,两三个人做一个模块,到最后快要演示的时候,才把几个模块尝试连到一起做集成测试。结果就是,所有人坐在一起进行的进行各种接口的连接、调用,bug修补。一旦连接成功就兴奋到难以言表,仿佛很长一段时间的工作都没有这一下来得兴奋。系统可以集成后,一直都提心吊胆,担心其中某个东西会不会莫名挂掉,因为集成测试都是使用人肉测试的啊。在展示的时候,各种紧张,安排专人时时刻刻注意到服务器。在敏捷中,我们要求及早进行系统集成和和创建部署环境的脚本,每次CI的运行都是一次集成测试,都是一次服务器的部署。因此不用担心在realse的时候不能部署的情况。不过有一件事情是需要注意的,那就是数据库的迁移,在开发机器,测试服务器你还能每次部署的时候都干掉之前的数据库,重新创建,但是在部署到产品服务器的时候就需要小心了,在Java中我们可以用<a href="http://flywaydb.org/" target="_blank" rel="external">Flyway</a> 达到类似Rails中的 rake db migrate的效果。 </li>
</ul>
<p>另外,我认为 switch pair(变还你结对同事)、 code review(团队成员坐到一起对团队前一天提交的代码进行浏览、解读),这些都可以让整个团队共享更多的上下文,还可以检查出不到的代码,学习好的代码。<br>也许明年这个时候我对敏捷的看法又有不少新的见解,到时候再来分享。</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2013/11/05/run-jetty-7,-8-with-gradle/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2013/11/05/run-jetty-7,-8-with-gradle/" itemprop="url">使用Gradle 运行jetty 7, 8</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2013-11-05T17:02:58+08:00">
2013-11-05
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2014-09-28T16:22:49+08:00">
2014-09-28
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/gradle/" itemprop="url" rel="index">
<span itemprop="name">gradle</span>
</a>
</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/gradle/java/" itemprop="url" rel="index">
<span itemprop="name">java</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>为什么我有这个需求呢? 作为一个使用Gradle的新手,今天在尝试将我之前的一个小应用从maven转向 gradle的时候,发现官方的jetty gradle plugin 不能正常运行我的应用,抛出的异常是: </p>
<blockquote>
<p>java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getServletContext()Ljavax/servlet/ServletContext;</p>
</blockquote>
<p>经过搜索后发现,这是因为 jetty容器中的 servlet API 不是3.0 版本的缘故,继续查证,发现 目前gradle 官方的jetty plugin 版本只支持jetty 6,而 jetty 6 里面的servlet 的版本是2.5。这是从一个Gradle的核心developer那里得到的答案。 </p>
<blockquote>
<p>Gradles Jetty plugin is outdated and only supports Jetty 6. </p>
</blockquote>
<p>因此我只能转而向其他途径去解决这个问题,最终发现了Cargo,其官方网站中对Cargo 的解释是: </p>
<blockquote>
<p>Cargo is a thin wrapper that allows you to manipulate Java EE containers in a standard way. </p>
</blockquote>
<p>简单讲Cargo是一个包装器,让你可以很简单的将你的应用使用类似的配置部署在各种应用服务器上运行。这里我们将使用cargo-gradle-plugin来解决问题: </p>
<p>首先应用插件,在你的build.gradle中添加对plugin的导入和添加依赖。<br><figure class="highlight groovy"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line">apply <span class="string">plugin:</span> <span class="string">'cargo'</span></div><div class="line"></div><div class="line">buildscript &#123;</div><div class="line"> repositories &#123;</div><div class="line"> mavenCentral()</div><div class="line"> &#125;</div><div class="line"></div><div class="line"> dependencies &#123;</div><div class="line"> classpath <span class="string">'org.gradle.api.plugins:gradle-cargo-plugin:0.6.1'</span></div><div class="line"> &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">dependencies &#123;</div><div class="line"> <span class="keyword">def</span> cargoVersion = <span class="string">'1.3.3'</span></div><div class="line"> cargo <span class="string">"org.codehaus.cargo:cargo-core-uberjar:$cargoVersion"</span>,</div><div class="line"> <span class="string">"org.codehaus.cargo:cargo-ant:$cargoVersion"</span></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>其次是就是cargo的详细配置了,如,选择你希望运行的WEB 容器,部署的应用和端口等。下面是我的配置:<br><figure class="highlight groovy"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line">cargo &#123;</div><div class="line"> containerId = <span class="string">'jetty8x'</span></div><div class="line"> port = <span class="number">8080</span></div><div class="line"></div><div class="line"> deployable &#123;</div><div class="line"> file = file(<span class="string">'build/libs/MessagePushX-0.0.1-SNAPSHOT.war'</span>)</div><div class="line"> context = <span class="string">'/'</span></div><div class="line"> &#125;</div><div class="line"></div><div class="line"> local &#123;</div><div class="line"> installer &#123;</div><div class="line"> installUrl = <span class="string">'http://mirrors.yun-idc.com/eclipse//jetty/stable-8/dist/jetty-distribution-8.1.13.v20130916.tar.gz'</span></div><div class="line"> downloadDir = file(<span class="string">"$buildDir/download"</span>)</div><div class="line"> extractDir = file(<span class="string">"$buildDir/extract"</span>)</div><div class="line"> &#125;</div><div class="line"> <span class="comment">// homeDir = file('/Users/twer/Documents/lib/jetty-8.1')</span></div><div class="line"> &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p><strong>containerId</strong>这是选择运行的容器ID,ID可以在Cargo的官方网站找到。基本上主流的java 服务器都支持,Tomcat, Jboss, Jetty等。<br><strong>port</strong> 应用运行的端口<br><strong>deployable</strong> 填入你希望运行的WAR包的地址,可以一次部署多个war包,如果部署多个就需要多个deployable节点。<br><strong>local</strong> 这里是你的配置你的WEB 容器的地址,你可以选择installer从远程下载,cargo会自动帮你解压,安装,运行;另外一种是homeDir 填写本地的WEB容器所在的文件夹。 </p>
<p>当这一切都完成后,你就可以使用 Gradle cargoRunLocal来运行你的应用了。<br>我今天测试过 Jetty 7,Jetty 8,Tomcat 7这些都是可以正常运行的,另外一个不能正常运行的是 Jetty 9,报的错误是,没有设置jetty.home 的值。但是我们有Jetty 8,应该能满足你的需要了吧,当然最希望的还是Gradle 官方升级jetty plugin的版本吧!</p>
<p><strong> 附录:</strong><br><a href="http://cargo.codehaus.org/" target="_blank" rel="external">Cargo</a><br><a href="https://github.com/bmuschko/gradle-cargo-plugin" target="_blank" rel="external">Cargo-gradle-plugin</a><br><a href="https://github.com/wahyd4/maven-to-gradle-sample" target="_blank" rel="external">我的示例地址</a> </p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://toozhao.com/2013/10/28/how-a-graduate-become-a-qualified-programmer/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Junv">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="大染志">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2013/10/28/how-a-graduate-become-a-qualified-programmer/" itemprop="url">毕业生成长记——如何成长为一个合格的程序员</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2013-10-28T09:07:17+08:00">
2013-10-28
</time>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于&#58;</span>
<time title="更新于" itemprop="dateModified" datetime="2013-10-28T09:15:05+08:00">
2013-10-28
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/我说/" itemprop="url" rel="index">
<span itemprop="name">我说</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<pre><code>上周六去成都Open Party 讲了自己怎么从一个毕业生成长为一个合格的程序员的感想吧,的确自己还有很多问题,最主要的是对自己写的东西和对自己的演讲不够自信,然后分享的的东西有些零零散散,希望以后可以在这方面做得越来越好。
</code></pre><p>还是把PPT分享出来吧,也算做是一篇博客,这个东西还是花了我不少心思在里面的。</p>
<script async class="speakerdeck-embed" data-id="581fada0219a01317a7f3af527e709f2" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
</section>
<nav class="pagination">
<span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><span class="space">&hellip;</span><a class="page-number" href="/page/31/">31</a><a class="extend next" rel="next" href="/page/2/"><i class="fa fa-angle-right"></i></a>
</nav>
</div>
</div>
<div class="sidebar-toggle">
<div class="sidebar-toggle-line-wrap">
<span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
<span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
<span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
</div>
</div>
<aside id="sidebar" class="sidebar">
<div class="sidebar-inner">
<section class="site-overview sidebar-panel sidebar-panel-active">
<div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
<img class="site-author-image" itemprop="image"
src="/images/avatar.gif"
alt="Junv" />
<p class="site-author-name" itemprop="name">Junv</p>
<p class="site-description motion-element" itemprop="description">Go, JavaScript, Ruby on Rails, Java, Git, Docker, CI, CD, HTML5, 创新, 拍照, 创业, Cordova</p>
</div>
<nav class="site-state motion-element">
<div class="site-state-item site-state-posts">
<a href="/archives/">
<span class="site-state-item-count">304</span>
<span class="site-state-item-name">日志</span>
</a>
</div>
<div class="site-state-item site-state-categories">
<span class="site-state-item-count">69</span>
<span class="site-state-item-name">分类</span>
</div>
<div class="site-state-item site-state-tags">
<span class="site-state-item-count">244</span>
<span class="site-state-item-name">标签</span>
</div>
</nav>
<div class="links-of-author motion-element">
<span class="links-of-author-item">
<a href="https://github.com/wahyd4" target="_blank" title="GitHub">
<i class="fa fa-fw fa-github"></i>
GitHub
</a>
</span>
<span class="links-of-author-item">
<a href="https://www.linkedin.com/in/junwei-zhao-46944557" target="_blank" title="LinkedIn">
<i class="fa fa-fw fa-linkedin"></i>
LinkedIn
</a>
</span>
</div>
</section>
</div>
</aside>
</div>
</main>
<footer id="footer" class="footer">
<div class="footer-inner">
<div class="copyright" >
&copy;
<span itemprop="copyrightYear">2017</span>
<span class="with-love">
<i class="fa fa-heart"></i>
</span>
<span class="author" itemprop="copyrightHolder">Junv</span>
</div>
</div>
</footer>
<div class="back-to-top">
<i class="fa fa-arrow-up"></i>
</div>
</div>
<script type="text/javascript">
if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
window.Promise = null;
}
</script>
<script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
<script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
<script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
<script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
<script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
<script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
<script type="text/javascript" src="/js/src/utils.js?v=5.1.2"></script>
<script type="text/javascript" src="/js/src/motion.js?v=5.1.2"></script>
<script type="text/javascript" src="/js/src/affix.js?v=5.1.2"></script>
<script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.2"></script>
<script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.2"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.2"></script>
<script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.2"></script>
</body>
</html>