<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>linjunhalida (机械唯物主义)</title>
    <link>https://ruby-china.org/linjunhalida</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>用了 importmap 之后，本地的 js 脚本怎么打包？</title>
      <description>&lt;p&gt;importmap 单独 load 一个个 js 库，但是项目自己的 js 怎么处理？查了一下 rails 官方文档没有介绍。&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Sat, 20 May 2023 20:34:55 +0800</pubDate>
      <link>https://ruby-china.org/topics/43091</link>
      <guid>https://ruby-china.org/topics/43091</guid>
    </item>
    <item>
      <title>[美国远程全职] 艾迪福克斯 2 名 Ruby 高级工程师：在家工作不加班，待遇优厚发美元</title>
      <description>&lt;p&gt;我司又开始招聘了，在家工作不加班，待遇优厚发美元，为什么这么好的工作大家不来抢呢？
上次招聘的一名Rails和一名C#已入职，现扩展团队，招聘 Rails 2 名，以下是详细介绍。&lt;/p&gt;
&lt;h2 id="关于我们"&gt;关于我们&lt;/h2&gt;
&lt;p&gt;我们是美国保险市场上摸爬滚打十余载的小公司，我们是创新，自由，追求卓越的团队。&lt;/p&gt;

&lt;p&gt;现有十多年运营使用的C#网站产品（&lt;a href="http://www.focussi.com/cba.aspx" rel="nofollow" target="_blank" title=""&gt;网站介绍&lt;/a&gt;），以及若干 Rails 支持网站。&lt;/p&gt;

&lt;p&gt;公司成员十余人，都是远程工作，分布在美国和中国各地，内部采用英文口语交流。&lt;/p&gt;

&lt;p&gt;我们和一些卡车保险领域公司建立长期合作关系，现金流良好，业绩和客户都在持续增长中。
因此现团队拓充，需要 Rails 高级工程师 2 名。&lt;/p&gt;
&lt;h2 id="Ruby 高级工程师"&gt;Ruby 高级工程师&lt;/h2&gt;
&lt;p&gt;职责描述&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;开发和维护保险文档系统&lt;/li&gt;
&lt;li&gt;保险信息化产品的定制化&lt;/li&gt;
&lt;li&gt;多个 Rails 和 C# 系统整合&lt;/li&gt;
&lt;li&gt;完成客户提出的需求&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;职位要求&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;计算机相关专业，Ruby 工作经验 4 年以上&lt;/li&gt;
&lt;li&gt;对 Ruby，Rails，SQL 的写法，用法了熟于心，掌握 html/js/css 前端开发&lt;/li&gt;
&lt;li&gt;追求对技术和业务的本质理解，对各种新鲜技术有很强的判断能力&lt;/li&gt;
&lt;li&gt;用数据，代码和事实说话，对代码质量有要求&lt;/li&gt;
&lt;li&gt;具有团队合作精神，乐于帮助他人，善于沟通&lt;/li&gt;
&lt;li&gt;具有英语口语交流能力&lt;/li&gt;
&lt;li&gt;通过面试&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="关于职位"&gt;关于职位&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;工资待遇：同比一线互联网公司，contractor 形式，直接发美元工资&lt;/li&gt;
&lt;li&gt;工作方式：远程工作，可适当调整工作时间，每周工作五天，不加班，放美国假&lt;/li&gt;
&lt;li&gt;联系方式：james.lin at focussi dot com 请发中英文简历。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;有疑问可加我个人微信：linjunhalida。&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Mon, 10 Jul 2017 22:56:24 +0800</pubDate>
      <link>https://ruby-china.org/topics/33452</link>
      <guid>https://ruby-china.org/topics/33452</guid>
    </item>
    <item>
      <title>如何一个人管理一堆服务器</title>
      <description>&lt;p&gt;博客链接： &lt;a href="http://blog.linjunhalida.com/blog/server-architecture-configuration-management/" rel="nofollow" target="_blank"&gt;http://blog.linjunhalida.com/blog/server-architecture-configuration-management/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;现在有一些服务器自动化配置工具，比如 ansible，chef，puppet 等，
利用它们，可以实现我的一个想法：用配置文件定义服务器架构。&lt;/p&gt;

&lt;p&gt;比如用 ansible，我们可以用一个 YAML 文件申明一台服务器上面有什么：安装了什么应用，存在什么配置文件，跑了什么服务。
然后用命令行工具，比如 ansible-playbook，就可以构建出来这样的服务器。&lt;/p&gt;

&lt;p&gt;这样操作的优点：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;可视化：原先服务器手工构建，其他人，甚至构建者自己都会不清楚服务器的状况。现在有了配置文件，大家就可以知道服务器上面有什么，是如何配置的。&lt;/li&gt;
&lt;li&gt;自动化：可以一条命令构建服务器，修改配置文件之后可以批量改动影响到的服务器，增加带有同样应用的服务器也非常简单，只要拷贝配置即可。如何搭建应用的知识可以复用。&lt;/li&gt;
&lt;li&gt;版本控制架构变更：可以用 git 版本库管理服务器配置文件，我们可以记录每次服务器架构的变更了。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;具体操作：针对一组服务器架构，比如一个 Rails 应用以及附属的各个服务器，
可以创建一个 git 版本库记录所有的 ansible playbook，
然后把敏感的配置文件，放到另外一个私密 git 版本库里面，
&lt;a href="http://blog.linjunhalida.com/blog/encrypted-git-repo/" rel="nofollow" target="_blank" title=""&gt;加密存储&lt;/a&gt;，保障安全性。&lt;/p&gt;

&lt;p&gt;我搭建了一个演示用例，包括：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/halida/haterslist" rel="nofollow" target="_blank" title=""&gt;一个 Rails 应用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/halida/haterslist_ansible" rel="nofollow" target="_blank" title=""&gt;ansible 配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/halida/haterslist_conf" rel="nofollow" target="_blank" title=""&gt;私密配置&lt;/a&gt;（仅限于演示）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;里面包含几台服务器：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/halida/haterslist_ansible/blob/master/playbooks/app.yml" rel="nofollow" target="_blank" title=""&gt;app.yml&lt;/a&gt;
搭建 Rails 服务器，包括 mysql 数据库，nginx，systemd 自动启动和监控脚本。&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/halida/haterslist_ansible/blob/master/playbooks/backup.yml" rel="nofollow" target="_blank" title=""&gt;backup.yml&lt;/a&gt;
自动备份 mysql 数据库&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/halida/haterslist_ansible/blob/master/playbooks/zabbix.yml" rel="nofollow" target="_blank" title=""&gt;zabbix.yml&lt;/a&gt;
对应的监控服务器（未完工）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;私密配置版本库里面存放了所有的配置文件，构建一些应用需要的用户名和密码，一些初始化数据等。
在 playbook 里面会去读取这些配置文件，或者拷贝这些文件到服务器上面去。&lt;/p&gt;

&lt;p&gt;管理 Rails 应用还需要一些其他的功能，限于时间，我就没有实现了，包括：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;jenkins 自动化测试&lt;/li&gt;
&lt;li&gt;sandbox，staging 环境&lt;/li&gt;
&lt;li&gt;mysql 多主从架构&lt;/li&gt;
&lt;li&gt;多 app 负载均衡&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;综上所述，一个复杂的多服务器应用架构，可以用上面的几个版本库定义出来，并且可以根据需要动态进行修改。
这种配置方式适用于几十台机器之内的半静态架构，并且可以多人同时管理。&lt;/p&gt;

&lt;p&gt;更进一步，如果利用 aws 或者 digitalocean 的 api，服务器创建也可以采用配置文件定义。
不过我觉得使用起来并不是很方便，就没有这样做了。&lt;/p&gt;

&lt;p&gt;如果机器数量多，或者需要动态伸缩，配置文件可能就不太适合了，可以用 ansible-tower 这种在线配置管理工具。
不过我觉得大多数的公司都不会达到这样的级别，因此配置文件就够用了。&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Sun, 09 Jul 2017 10:43:04 +0800</pubDate>
      <link>https://ruby-china.org/topics/33437</link>
      <guid>https://ruby-china.org/topics/33437</guid>
    </item>
    <item>
      <title>[美国远程全职] 艾迪福克斯 1 名 Ruby 高级工程师，1 名 C# 高级工程师</title>
      <description>&lt;p&gt;我司又开始招聘了，在家工作不加班，待遇优厚发美元，为什么这么好的工作大家不来抢呢？&lt;/p&gt;

&lt;p&gt;要求 Rails 或 C#熟手，英语口语可以交流。以下是详细介绍。&lt;/p&gt;
&lt;h2 id="关于我们"&gt;关于我们&lt;/h2&gt;
&lt;p&gt;我们是美国保险市场上摸爬滚打十余载的小公司，我们是创新，自由，追求卓越的团队。&lt;/p&gt;

&lt;p&gt;现有十多年运营使用的&lt;a href="http://www.focussi.com/cba.aspx" rel="nofollow" target="_blank" title=""&gt;C#网站产品&lt;/a&gt;，以及若干 Rails 支持网站。&lt;/p&gt;

&lt;p&gt;公司成员十余人，都是远程工作，分布在美国和中国各地，内部采用英文口语交流。&lt;/p&gt;

&lt;p&gt;我们和一些卡车保险领域公司建立长期合作关系，现金流良好，业绩和客户都在持续增长中。
因此现团队拓充，需要Rails高级工程师和C#高级工程师各一名。&lt;/p&gt;
&lt;h2 id="Ruby 高级工程师"&gt;Ruby 高级工程师&lt;/h2&gt;
&lt;p&gt;职责描述&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;开发和维护保险文档系统&lt;/li&gt;
&lt;li&gt;保险产品的定制化&lt;/li&gt;
&lt;li&gt;安全系统&lt;/li&gt;
&lt;li&gt;多个 Rails 和 C# 系统整合，例如 自己写的系统和 redmine 整合，比如 SSO 整合&lt;/li&gt;
&lt;li&gt;完成客户提出的需求&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;职位要求&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;计算机专业，Ruby 工作经验 4 年以上&lt;/li&gt;
&lt;li&gt;对 Ruby，Rails，SQL 的写法，用法了熟于心&lt;/li&gt;
&lt;li&gt;对各种新鲜技术有很强的判断能力&lt;/li&gt;
&lt;li&gt;用数据，代码和事实说话&lt;/li&gt;
&lt;li&gt;具有团队合作精神，乐于帮助他人&lt;/li&gt;
&lt;li&gt;前端 html/css/js 自然不用多说&lt;/li&gt;
&lt;li&gt;英语口语交流能力&lt;/li&gt;
&lt;li&gt;通过面试&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="C#高级工程师"&gt;C#高级工程师&lt;/h2&gt;
&lt;p&gt;职责描述&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;负责汽车保险系统的维护和开发，负责 report, batch, integration, API 等&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;职位要求&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;计算机专业，C# 工作经验 5 年以上&lt;/li&gt;
&lt;li&gt;有丰富的产品开发经验，曾经独立设计过项目架构&lt;/li&gt;
&lt;li&gt;对 设计模式 有深刻的理解&lt;/li&gt;
&lt;li&gt;具有团队合作精神，有很强的自制力&lt;/li&gt;
&lt;li&gt;英语口语交流能力&lt;/li&gt;
&lt;li&gt;通过面试&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="关于职位"&gt;关于职位&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;工资待遇：同比一线互联网公司，contractor 形式，直接发美元工资&lt;/li&gt;
&lt;li&gt;工作方式：远程工作，可适当调整工作时间，每周工作五天，不加班，放美国假&lt;/li&gt;
&lt;li&gt;联系方式：james.lin at focussi dot com 请发中英文简历。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;有疑问可加我个人微信：linjunhalida。&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Mon, 17 Apr 2017 16:29:11 +0800</pubDate>
      <link>https://ruby-china.org/topics/32800</link>
      <guid>https://ruby-china.org/topics/32800</guid>
    </item>
    <item>
      <title>Ruby 需要一个静态类型验证系统</title>
      <description>&lt;p&gt;&lt;a href="http://blog.linjunhalida.com/blog/ruby-need-static-type-checking-system/" rel="nofollow" target="_blank" title=""&gt;拷贝自我的博客&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;越用 Ruby，越觉得 Ruby 简陋。很多其它现代语言有的特性，Ruby 都没有。其中一个就是静态类型验证系统。&lt;/p&gt;

&lt;p&gt;Ruby 语言里面，是不需要定义函数的参数，以及变量的类型的，这样带来的好处就是写程序更简便了，这个被大家称为是优点。
但是实际上，这是一个缺陷。为什么呢？&lt;/p&gt;

&lt;p&gt;程序在执行的过程中，如果不知道一个变量的类型，只能动态去判断变量是什么，动态地查找处理变量的函数，
比如一个方法调用：&lt;code&gt;a.run(b)&lt;/code&gt;，就要去查找 a 的 run 方法，然后传入 b 参数。
这样造成每次函数调用，都会进行一次判断和查找，极大地降低程序执行速度。&lt;/p&gt;

&lt;p&gt;另外一个问题就是，当传入的参数不正确 (比如 a 没有 run 方法，或者 run 只接受一个参数)，只有程序实际执行的时候，才会知道这点。
一方面要在函数和方法调用的时候来判断（更慢了），另外一方面本来能够静态识别出来的错误，留到了运行时。&lt;/p&gt;

&lt;p&gt;更可怕的是，当传入的参数类型错误的时候，不能立刻就知道，而是要等到很久之后才会被发现，
这个时候你根本不知道这个参数是什么时候传进来的，Debug 变得非常困难！
其它语言定义了类型，在编译的时候就可以发现这样的错误，但是动态类型语言，比如 Ruby/Python 就没有办法。&lt;/p&gt;

&lt;p&gt;在实际进行 Ruby 编程的时候，我深刻地体会到了这几点。
尤其是项目变得很大的时候，执行速度不说，出现问题找 Bug 变得很困难，
程序可靠性没有办法通过编译阶段发现，而是只能留到执行时（testcase），
并且执行时也做不到其它静态语言级别的函数参数类型验证。&lt;/p&gt;

&lt;p&gt;而在其它现代语言里面，类型定义不再向以前一样手动配置那么痛苦了。
比如在C#里面，我们可以定义函数参数的类型，以及所有变量的类型，也可以不定义（dynamic），做到和Ruby一样的效果。
但是还有更好的语法 (var)，程序语言自动给你做好类型定义，不用自己手写了，方便很多。&lt;/p&gt;

&lt;p&gt;综上所述，静态类型验证系统是现代程序语言必备的一个功能，Ruby 不应该缺少这样的功能。
Matz 本人也说，下一阶段会进行这种系统的设计。
不过我觉得这么大的改动，只有在程序语言开始设计的时候才能做出，Ruby 现在已经进入成熟阶段，再改就很难了。
Racket 语言的解决方案是拆分成带有 Typed 和没有 Typed 的两个子集。&lt;/p&gt;

&lt;p&gt;如果不是 Rails，我可能会考虑其它语言，但是谁让 web 开发框架里面，Rails 生态圈最好最成熟呢。&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Sun, 12 Mar 2017 22:41:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/32513</link>
      <guid>https://ruby-china.org/topics/32513</guid>
    </item>
    <item>
      <title>[美国远程全职] 美国艾迪福克斯 1 名 高级 Ruby 工程师，1 名 高级 C# 工程师　</title>
      <description>&lt;p&gt;我司又开始招聘了，在家工作不加班，待遇优厚发美元，为什么这么好的工作大家不来抢呢？&lt;/p&gt;

&lt;p&gt;要求 Rails 或 C#熟手，英语口语可以交流。以下是详细介绍。&lt;/p&gt;
&lt;h2 id="关于我们"&gt;关于我们&lt;/h2&gt;
&lt;p&gt;我们是美国保险市场上摸爬滚打十余载的小公司，我们是创新，自由，追求卓越的团队。&lt;/p&gt;

&lt;p&gt;现有十多年运营使用的&lt;a href="http://www.focussi.com/cba.aspx" rel="nofollow" target="_blank" title=""&gt;C#网站产品&lt;/a&gt;，以及若干 Rails 支持网站。&lt;/p&gt;

&lt;p&gt;公司成员十余人，都是远程工作，分布在美国和中国各地，内部采用英文口语交流。&lt;/p&gt;

&lt;p&gt;我们和一些卡车保险领域公司建立长期合作关系，现金流良好，业绩和客户都在持续增长中。
因此现团队拓充，需要 2 名高级工程师。&lt;/p&gt;
&lt;h2 id="Ruby 高级工程师"&gt;Ruby 高级工程师&lt;/h2&gt;
&lt;p&gt;职责描述&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;开发和维护保险文档系统&lt;/li&gt;
&lt;li&gt;保险产品的定制化&lt;/li&gt;
&lt;li&gt;安全系统&lt;/li&gt;
&lt;li&gt;多个 Rails 和 C# 系统整合，例如 自己写的系统和 redmine 整合，比如 SSO 整合&lt;/li&gt;
&lt;li&gt;完成客户提出的需求&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;职位要求&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;计算机专业，Ruby 工作经验 4 年以上&lt;/li&gt;
&lt;li&gt;对 Ruby，Rails，SQL 的写法，用法了熟于心&lt;/li&gt;
&lt;li&gt;对各种新鲜技术有很强的判断能力&lt;/li&gt;
&lt;li&gt;用数据，代码和事实说话&lt;/li&gt;
&lt;li&gt;具有团队合作精神，乐于帮助他人&lt;/li&gt;
&lt;li&gt;前端 html/css/js 自然不用多说&lt;/li&gt;
&lt;li&gt;英语口语交流能力&lt;/li&gt;
&lt;li&gt;通过面试&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="C#高级工程师"&gt;C#高级工程师&lt;/h2&gt;
&lt;p&gt;职责描述&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;负责汽车保险系统的维护和开发，负责 report, batch, integration, API 等&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;职位要求&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;计算机专业，C# 工作经验 5 年以上&lt;/li&gt;
&lt;li&gt;有丰富的产品开发经验，曾经独立设计过项目架构&lt;/li&gt;
&lt;li&gt;对 设计模式 有深刻的理解&lt;/li&gt;
&lt;li&gt;具有团队合作精神，有很强的自制力&lt;/li&gt;
&lt;li&gt;英语口语交流能力&lt;/li&gt;
&lt;li&gt;通过面试&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="关于职位"&gt;关于职位&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;工资待遇：同比一线互联网公司，contractor 形式，直接发美元工资&lt;/li&gt;
&lt;li&gt;工作方式：远程工作，可适当调整工作时间，每周工作五天，不加班，放美国假&lt;/li&gt;
&lt;li&gt;联系方式：james.lin at focussi dot com 请发中英文简历。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;有疑问可加我个人微信：linjunhalida。&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Tue, 07 Mar 2017 22:31:38 +0800</pubDate>
      <link>https://ruby-china.org/topics/32478</link>
      <guid>https://ruby-china.org/topics/32478</guid>
    </item>
    <item>
      <title>大家在生产服务器上面用什么发行版？如何保证服务器安全？</title>
      <description>&lt;p&gt;回去看了一下讨论： &lt;a href="https://www.zhihu.com/question/19599986" rel="nofollow" target="_blank"&gt;https://www.zhihu.com/question/19599986&lt;/a&gt; 
看起来建议是：RHEL，debian，ubuntu 这 3 个选项。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RHEL：收费，保证安全补丁及时更新&lt;/li&gt;
&lt;li&gt;debian：稳定&lt;/li&gt;
&lt;li&gt;ubuntu：流行，比较熟悉&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;现在我们用的是 ubuntu，要不要换 debian，或者 RHEL，请问大家是怎么考虑的？&lt;/p&gt;

&lt;p&gt;rails 一般是小团队，往往没有专职的运维，我很担心这种情况下服务器是否能够保障安全。
运维的很多经验和实施策略，普通开发人员是很难学习到和做到的。
请问大家是否也有这方面的顾虑？&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Tue, 05 Jul 2016 23:03:15 +0800</pubDate>
      <link>https://ruby-china.org/topics/30460</link>
      <guid>https://ruby-china.org/topics/30460</guid>
    </item>
    <item>
      <title>一个 SSL 验证错误的问题</title>
      <description>&lt;p&gt;一个随机出现的问题：&lt;/p&gt;

&lt;p&gt;架构：Rails + sidekiq + rest-client，服务器 A（国外 aws 上面），上面跑了好多的 rails 应用，提供 API&lt;/p&gt;

&lt;p&gt;从服务器 A 上面的应用 R1 发起一个 http delete 请求到服务器 A 的应用 B，偶尔会出现报错：&lt;/p&gt;

&lt;p&gt;RestClient::SSLCertificateNotVerified: SSL_connect returned=1 errno=0
state=SSLv3 read server certificate B: certificate verify failed&lt;/p&gt;

&lt;p&gt;并且是两个 sidekiq worker 同时发生这个报错&lt;/p&gt;

&lt;p&gt;个人猜测：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;发起请求的地址是域名地址，包是跑到外面再跑回来的，中间有网络问题&lt;/li&gt;
&lt;li&gt;http delete 包在传输过程中受到的不公平对待（ssl 应该不太可能吧？）&lt;/li&gt;
&lt;li&gt;ssl 协议 certificate 传输过程中丢包，或者服务器处理 certificate 过程中出错（超时，数据传输不完整，丢包？）&lt;/li&gt;
&lt;li&gt;rest-client 或者 ruby 库有问题，偶尔会发生这种现象&lt;/li&gt;
&lt;li&gt;服务器 A 当时状况不稳定，影响到了（怎么影响的？）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;请问大家有没有遇到类似的状况，以及如何解决？谢谢~&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Tue, 01 Mar 2016 09:45:26 +0800</pubDate>
      <link>https://ruby-china.org/topics/29162</link>
      <guid>https://ruby-china.org/topics/29162</guid>
    </item>
    <item>
      <title>关于如何搭建一个核心管理服务器的问题</title>
      <description>&lt;p&gt;一个很常见的问题：
小团队，几个开发者，一堆的服务器，每个开发者有部分服务器的操作权限。
简单的管理：每个服务器上面大家自己加自己的 ssh pubkey，需要的时候登录服务器操作。&lt;/p&gt;

&lt;p&gt;缺点：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;服务器开放 ssh 端口，非常不安全&lt;/li&gt;
&lt;li&gt;服务器上面谁登录了不知道，因为大家都用同一个 admin 帐号（比如 ubuntu）&lt;/li&gt;
&lt;li&gt;难以修改 ssh key，需要登录到服务器上面去改&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我想的解决方案：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;一个核心堡垒机，很完善的安全加固&lt;/li&gt;
&lt;li&gt;服务器只开放 ssh 给堡垒机&lt;/li&gt;
&lt;li&gt;堡垒机设置用户，他们的 pubkey，以及可以访问的服务器权限&lt;/li&gt;
&lt;li&gt;监控用户操作，记录日志，发现问题告警&lt;/li&gt;
&lt;li&gt;堡垒机挂掉后有应急访问服务器的方案&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;请问大家有没有类似的开源或者公开的解决方案吗？谢谢~&lt;/p&gt;

&lt;p&gt;这个问题我在 SO 上面提问了： &lt;a href="http://serverfault.com/questions/733205/centralized-audit-server-solution-for-mutiple-server-management" rel="nofollow" target="_blank"&gt;http://serverfault.com/questions/733205/centralized-audit-server-solution-for-mutiple-server-management&lt;/a&gt;&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Mon, 02 Nov 2015 16:23:50 +0800</pubDate>
      <link>https://ruby-china.org/topics/27926</link>
      <guid>https://ruby-china.org/topics/27926</guid>
    </item>
    <item>
      <title>在所有 js 插件渲染好页面之后，再显示页面</title>
      <description>&lt;p&gt;现在页面用了一堆的插件，比如 select2，datepicker 等，每次页面显示出来都会抖动一下（首先是显示没有经过这些插件处理的组件，然后这些插件处理完毕后，页面元素变化了）。&lt;/p&gt;

&lt;p&gt;请问大家是这样解决这些问题的？&lt;/p&gt;

&lt;p&gt;我以前用的方法：
body 加上 class：loading，css 设置页面透明，页面上方一个加载中的提示。
然后渲染好之后给 body 加上 class loaded，css 把页面显示出来，隐藏加载中提示。&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Mon, 19 Oct 2015 16:09:36 +0800</pubDate>
      <link>https://ruby-china.org/topics/27729</link>
      <guid>https://ruby-china.org/topics/27729</guid>
    </item>
    <item>
      <title>Resque 如何设置直接执行？</title>
      <description>&lt;p&gt;需要测试 Resque 的任务，但是不想跑 worker（队列里面好多垃圾任务），希望可以在初始化的时候设置一下 Resque，让它直接跑，
 我在文档里面没有翻到配置，请问有谁知道的呀？&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Fri, 04 Sep 2015 11:44:55 +0800</pubDate>
      <link>https://ruby-china.org/topics/27190</link>
      <guid>https://ruby-china.org/topics/27190</guid>
    </item>
    <item>
      <title>RSpec 语法怎么变得那么傻了？</title>
      <description>&lt;p&gt;好久没写 rspec，回头一看：&lt;/p&gt;

&lt;p&gt;&lt;a href="http://rspec.info/documentation/3.1/rspec-core/" rel="nofollow" target="_blank"&gt;http://rspec.info/documentation/3.1/rspec-core/&lt;/a&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# in spec/calculator_spec.rb&lt;/span&gt;
&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'#add'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;'returns the sum of its arguments'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;原先用&lt;code&gt;Calculator.new.add(1, 2).should == 3&lt;/code&gt;多简洁，为什么改成了这种写法？还不如 Test::Unit 的方法&lt;code&gt;assert_equal&lt;/code&gt;呢。&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Mon, 29 Jun 2015 14:58:50 +0800</pubDate>
      <link>https://ruby-china.org/topics/26235</link>
      <guid>https://ruby-china.org/topics/26235</guid>
    </item>
    <item>
      <title>一个奇怪的问题，Rails 缓存代码还是 Ruby 缓存代码</title>
      <description>&lt;p&gt;Rails 项目里面的 config/application.rb 里面，加了一行：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;APP_CONFIG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;HashWithIndifferentAccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;YAML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expand_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'../app_config.yml'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;))[&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就可以访问一些配置，在所有其他文件都可以用：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;APP_CONFIG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:aws&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:access_key_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是遇到一个奇怪的问题，修改了 app_config.yml 的内容，进入&lt;code&gt;rails console&lt;/code&gt;，APP_CONFIG 获取的还是旧的信息，然后修改了一下 application.rb，信息才更新过来了。
请问大家这是怎么回事？是 ruby 还是 rails 里面做了缓存？&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Fri, 29 May 2015 08:43:28 +0800</pubDate>
      <link>https://ruby-china.org/topics/25798</link>
      <guid>https://ruby-china.org/topics/25798</guid>
    </item>
    <item>
      <title>更好的命令行</title>
      <description>&lt;p&gt;&lt;a href="http://blog.linjunhalida.com/blog/fuck-commandline/" rel="nofollow" target="_blank" title=""&gt;博客原文链接&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;命令行大家应该都熟悉了，但是命令行其实是很烂的，
输入和输出都采用字符串的方式，而不是一个规整的数据结构。
这样的后果是，每个程序都需要自己解析输入，以及提供一个特殊结构的输出，
很容易出现解析上面的问题。&lt;/p&gt;

&lt;p&gt;从本质上面说，命令行就是一个函数执行的接口，终端就是一个状态机，
每一个命令就是一个函数。那么为什么不像通用的编程语言的函数一样来定义？&lt;/p&gt;

&lt;p&gt;比如这样来写：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 普通操作&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Sat May 23 09:18:38 CST 2015"&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;rm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/fdas/fdas/fda'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;directory: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;force: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

&lt;span class="c1"&gt;# 输出结构化&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ls&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="ss"&gt;mode: &lt;/span&gt;&lt;span class="s1"&gt;'drwxr-xr-x'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user: &lt;/span&gt;&lt;span class="s1"&gt;'halida'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;group: &lt;/span&gt;&lt;span class="s1"&gt;'halida'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;size: &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Gemfile.lock'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;columns: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:size&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Gemfile.lock'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;size: &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# 管道&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:cmd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/mina/&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;cmd: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'mina init'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;run_at: &lt;/span&gt;&lt;span class="s1"&gt;'2014-02-01 10:00:21'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ls&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Gemfile.lock'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# 很多命令应该用面向对象的方式来执行，更容易理解&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'master'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;committer&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'James'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s1"&gt;'james@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# 输出日志就算是以文字的方式体现，也最好结构化起来，方便解析&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Process file (filename) finished, spend time (spendtime)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;filename: &lt;/span&gt;&lt;span class="s2"&gt;"xxx.mov"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;spendtime: &lt;/span&gt;&lt;span class="mi"&gt;220&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spendtime&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;220&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;网上搜索了一下，看起来没有什么好的解决方案，大家怎么看？&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Sat, 23 May 2015 09:23:55 +0800</pubDate>
      <link>https://ruby-china.org/topics/25712</link>
      <guid>https://ruby-china.org/topics/25712</guid>
    </item>
    <item>
      <title>服务器自动重启影响 Rails 后台任务的问题</title>
      <description>&lt;p&gt;服务器设置了自动镜像备份（AWS），备份的过程中，需要重启服务器。会有一些问题：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;服务器跑了 Resque 或者 Sidekiq，后台有任务在执行中，重启的时候，是等待任务执行完毕，还是让任务失败？&lt;/li&gt;
&lt;li&gt;服务器上面跑的 Redis 往往很快就关闭了，但是 Resque/Sidekiq 还保持连接，可能发生数据丢失的状况？&lt;/li&gt;
&lt;li&gt;服务器跑的 mysql 也会停止，如果比 Rails 进程更先停止，那么是否会发生数据丢失或者错误的状况？&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;根据以上问题，是否需要在操作系统层面上管理 Rails 进程？这样可以做依赖管理（比如用 systemd），请问大家的看法？&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Wed, 20 May 2015 14:56:35 +0800</pubDate>
      <link>https://ruby-china.org/topics/25670</link>
      <guid>https://ruby-china.org/topics/25670</guid>
    </item>
    <item>
      <title>Rails 导出数据经验整理</title>
      <description>&lt;p&gt;最近我做了一些 rails 数据导出的工作，就是把一些特定的 ActiveRecord 数据挖出来，保存到表格里面。
这里分享一些习得的经验~&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.linjunhalida.com/blog/rails-export-data/" rel="nofollow" target="_blank" title=""&gt;我的博客文章链接&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;需要注意这些事情：执行速度，内存消耗，以及调试速度。&lt;/p&gt;
&lt;h2 id="执行速度"&gt;执行速度&lt;/h2&gt;
&lt;p&gt;导数据的程序基本上就是一个循环体，外部获取数据集，内部把一条数据转换成表格。
在内部，往往需要通过一条记录作为主体，通过数据库逻辑关系顺藤摸瓜挖出一批数据，
这样会形成一批短查询，因为是在循环体里面，会带来很大时间上的消耗，比如：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_at"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;company&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以先把这些查询汇总起来，一次查询掉，然后在循环体内部筛选出对应的数据：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;out = []
units = Unit.where("active_at" &amp;lt; Time.now)
company_names = Company.where(id: units.pluck(:company_id).uniq).pluck(:id, :name).to_h
units.each do |unit|
  out &amp;lt;&amp;lt; [company_names[unit.company_id]]
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="内存消耗"&gt;内存消耗&lt;/h2&gt;
&lt;p&gt;查询大量数据的时候，可以首先查所有的 ID，然后分批查询，这样防止序列化大量的数据库对象：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;unit_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_at"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pluck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;group_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="n"&gt;unit_ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;in_groups_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;数据全部缓存在一个 array 中的话，会占用大量内存，最好是通过数据流的方式一个个输出处理，用后即丢：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;export&lt;/span&gt;
  &lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_at"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;CSV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'out.csv'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在循环体内部，尽量用局部变量，不用的资源会更早释放。&lt;/p&gt;

&lt;p&gt;跑数据导出的时候，最好同时注意一下服务器的剩余内存。不要把其它服务搞挂了。&lt;/p&gt;
&lt;h2 id="调试速度"&gt;调试速度&lt;/h2&gt;
&lt;p&gt;导数据最花费时间的往往还是调试过程。&lt;/p&gt;

&lt;p&gt;调试的时候，可以只返回几条数据，检查完毕之后再全部跑。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;debug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_at"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;debug&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要考虑数据并不是很规整，做好预防性编程。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_at"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;company&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt; &lt;span class="c1"&gt;# 公司可能不存在&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;很多时候难免特定数据不符合预设状况，最好循环体内部记录 log，出现问题可以跟踪。
比如下面的例子，unit 没有 oldest_driver 的时候，会报错，记录了日志，就知道在哪条上面出现了问题。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_at"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"unit: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;oldest_driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drivers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'age desc'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
  &lt;span class="c1"&gt;# &lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;ordest_driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;导出数据可以生成两个版本，一个给客户，另外一个加上一些 debug 数据方便自己分析。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;export&lt;/span&gt;
  &lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_at"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'debug'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;CSV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'out.csv'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="no"&gt;CSV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'out_debug.csv'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;debug_csv&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;debug_csv&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;
      &lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="架构设计"&gt;架构设计&lt;/h2&gt;
&lt;p&gt;代码架构上面最重要的是职责清晰。导出数据的逻辑比较简单，分离出导数据类，以及处理数据类就可以了：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Exporter&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;iterator_to_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;CSV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExportActiveUnits&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:time&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;export&lt;/span&gt;
    &lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_at"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;eau&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ExportActiveUnits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;eau&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
&lt;span class="no"&gt;Exporter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iterator_to_csv&lt;/span&gt; &lt;span class="s2"&gt;"out.csv"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eau&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:export&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Wed, 20 May 2015 14:48:47 +0800</pubDate>
      <link>https://ruby-china.org/topics/25669</link>
      <guid>https://ruby-china.org/topics/25669</guid>
    </item>
    <item>
      <title>File.write (filename, text) 是否线程安全？</title>
      <description>&lt;p&gt;请教一下大家，如果好几个进程同时调用 File.write(filename, text) ，是否会出现冲突？File.write 在写之前是否会锁文件？&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Sun, 19 Apr 2015 20:40:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/25204</link>
      <guid>https://ruby-china.org/topics/25204</guid>
    </item>
    <item>
      <title>为什么 Java 没有 GIL？</title>
      <description>&lt;p&gt;python 和 ruby 都有 GIL，但是好像一些其他语言没有 GIL，请问其他语言（比如 java）如何处理这个问题的？是所有库都有 lock 保证资源安全吗？&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Thu, 19 Mar 2015 23:49:53 +0800</pubDate>
      <link>https://ruby-china.org/topics/24739</link>
      <guid>https://ruby-china.org/topics/24739</guid>
    </item>
    <item>
      <title>ActiveRecord 设置数据库只读</title>
      <description>&lt;p&gt;需求是这样的：Rails 需要访问另外的数据库来查询资料，为了保证安全，希望可以设置数据库只读，但是同时在一些特殊情况下要可以更新部分数据。&lt;/p&gt;

&lt;p&gt;连接数据库的用户可以设置成只读用户，但是这样不能在有需要的时候写入数据了。数据库 Adapter 也没有设置成只读的功能。&lt;/p&gt;

&lt;p&gt;有一个思路，就是 hack adapter，设置只能够发送 select 语句，其他的都过滤报错，只有在手动开启开关的时候才可以发送其他语句。&lt;/p&gt;

&lt;p&gt;不知道大家怎么看？&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Thu, 19 Mar 2015 11:47:31 +0800</pubDate>
      <link>https://ruby-china.org/topics/24722</link>
      <guid>https://ruby-china.org/topics/24722</guid>
    </item>
    <item>
      <title>ubuntu 切换到 systemd 了，以后可以用 systemd 来管理 rails 进程</title>
      <description>&lt;p&gt;新闻：&lt;a href="http://www.cnbeta.com/articles/375417.htm" rel="nofollow" target="_blank"&gt;http://www.cnbeta.com/articles/375417.htm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;systemd 可以用来设置进程的访问权限，内存消耗，CPU 占用等，也可以按需启动，以后可以用 systemd 来管理 rails 进程，不再需要用 god，monit 等工具了。我觉得把进程监控和管理放在 init 层是非常合适的。&lt;/p&gt;

&lt;p&gt;大家怎么看？&lt;/p&gt;</description>
      <author>linjunhalida</author>
      <pubDate>Tue, 10 Mar 2015 12:33:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/24567</link>
      <guid>https://ruby-china.org/topics/24567</guid>
    </item>
  </channel>
</rss>
