网络寻租 http://blog.linjunhalida.com/ zh-cn © 2010, linjunhalida. 2012-01-06T16:04:00+00:00 电脑是如何实现图形显示的 http://blog.linjunhalida.com/article/电脑是如何实现图形显示的

今天去 hacking thursday 的活动, 听一位朋友介绍了一下关于电脑是如何处理图形显示的东西, 整体脉络清楚了一些, 趁着记忆没有消散, 这里稍微整理一下.

我们先从显示器说起. 显示器负责真正把图像呈现给我们, 一般现在我们的电脑显示器可以接收数字信号也可以接收模拟信号, 数字的一般用 DVI, 模拟的一般 VGA 的接口. 传给显示器的数据不神奇, 就是图像数据流, 每个点拆分成RGB红绿蓝3原色的数值表示. VGA还要带的是 horizontal sync, vertical sync, 这个是水平和垂直扫描率, 就是每秒钟横竖扫描多少条, 就是我们说的屏幕分辨率再乘上没秒钟屏幕的刷新率. 这个数据丢给显示器, 显示器里面也有CPU, 负责控制屏幕把这样的数据显示出来, 也可能对这个数据做一点微调什么的, 比如我们显示器一般都有的对颜色位置亮度饱和度的调整.

要传给显示器的数据量是非常巨大的(根据屏幕尺寸), 也需要不断地传数据给显示器. 具体负责这些操作的是显卡. 现代的显卡要做相当多的事情. 不止是不间断地发送视频, 还会有渲染(3d游戏场景的渲染主要工作是交给显卡来做的), 视频数据解码等工作. 与上层的接口一般是通过显卡来读取特定的内存区块(DMA等方式)来实现. 简单地说, 告诉显卡, 主内存里面一个区块存放了需要显示的数据, 然后显卡自己过来取数据, 上层应用定时往这个内存区块放数据.

显卡会有自己的一些做事情的方式, 对于上层应用来说, 这些都是实现细节, 不需要知道. 显卡厂商会把功能抽象成opengl的API, 然后上层应用就调用这样的API即可. 在linux里面, Xwindow做的事情就是提供一个server/client的接口, 具体接口还是opengl.

然后我们到了更上层的gnome/kde, 它们是提供关于窗口绘制的api, 再往上面就是应用程序了, 调用gui的库来设置控件, 交互什么的.

如果上层应用需要直接发送显示的东西怎么办? 比如视频. 这个时候调用opengl的api, 申请一块内存区, 把渲染好的特定数据结构的图像放到这个内存区, 然后用opengl通知下层显示即可. 上层应用的进程需要控制刷新率, 一秒30桢的话就要刷30次, 如果应用是一个播放器的话, 可能需要多个线程, 一个线程用来做用户交互, 一个线程用来刷屏幕, 一个线程用来处理数据编码. 显卡也可以做解码的工作, 播放器可以控制显卡来解码, 这样显卡直接解码后写到显卡的缓存区块里面去.

具体技术细节非常复杂, 但是对于我来说, 对整体的过程有一个概念即可. 知道了原理就行了.

机械唯物主义 2012-01-06T16:04:00+00:00
Metaprogramming_Ruby学习笔记 http://blog.linjunhalida.com/article/Metaprogramming_Ruby学习笔记

虽然我现在一直在用ruby做rails开发, 但是ruby基本上是属于拿起来用的那种, 很多东西都不是很熟悉.

现在发现有一本Metaprogramming Ruby的书, 就看起来了. 这里整理一下学习笔记, 省得学了白学. 下面其实只是一些tips, 只是给我自己看看的. 所以大家就不要抱有什么期待了.

星期一

Ruby是全运行态, 没有编译态(对于程序员而言).

Class本身也能运行时创建.

Ruby里面的Class继承自Module, 多了一些实例化, 继承的东西.

所有Class的class是Class, Class继承Module继承Object继承BasicObject.

method的查找方式, 先看object, 然后查Class树, 中间会穿插class include的Module.

所有位置都隐含一个self, 调用方法就是把调用者当作self, irb默认self是main.

private的method只能被隐含self的方式调用, self.private_method是不能调用的.

星期二

obj.send(:my_method, 3) 用来做动态方法调用.

define_method用来动态定义方法.

method_missing用来处理找不到方法的时候的状况.

还有undef_method, 这些方法可以用来做很多有意思的事情了.

星期三

回顾了block和using.

scope在class, model, def这3个阶层. 可以用Class.new, Module.new, Module@define_method动态生成.

有了instance_eval可以切换到object的scope里面去.

Proc, lambda可以保存block, &用来转换Proc和block.

Proc里面return是从定义Proc的scope里面return, 这个太恶心了吧? 还有不严格判断参数. 还是用lambda比较好.

星期四

class 也是 module, 在它们的作用域里面执行代码, 用module_eval.

我有点明白为什么不用缩进来限制作用域了, 缩进没有明确限制作用域来得灵活.

def并不会开启一个新的scope, 还是在class的scope里面.

在class里面用"@"定义instance variable, 用"@@"定义Class instance variable(真绕). 因为@@定义在类树里面, 容易产生bug, 不建议使用.

class method其实是singleton methods, 有趣.

每个object还有eigenclass. 用class << obj; self end; 这样的方式访问.

加上eigenclass, ruby的类树就比较复杂了, 不过看图就好理解一些.

alias和alias_method创建别名.

星期五

binding用来缓存作用域, 给eval用. TOPLEVEL_BINDING是最上层的binding.

class里面有无数事件的hook, 比如inherited, included, method_added.

最后一部分activerecord用到的魔法, 我就稍微带过了, 因为具体的方法我兴趣不是很大.

结论

上面只是给我自己总结的一些tip, 一些我已经知道的东西, 但是对其他人非常重要的地方没有写出来. 所以需要理解的话大家还是看书吧.

机械唯物主义 2012-01-01T22:31:00+00:00
2011年度总结 http://blog.linjunhalida.com/article/2011年度总结

有好几个朋友都写了年度总结, 我想如果没有反思的话就没有成长, 也写写年度总结吧.

分几个方面, 工作上, 生活上, 情感上什么的.

工作上

我这一年大部分的时间都在 新漫传感 这家公司工作. 今年11月底正式离职. 总共2年的时间. 我当时去到新漫的时候, 也是家里人朋友的介绍, 我也就去了. 总体上面来, 这份工作的自由度非常大, 任务其实也很明确. 闲暇时间非常多. 但是对于我来说是一个败笔. 在这家公司, 我做的事情没有什么可以说的(只是一份工, 不能让人对我做的事情眼前一亮, 更不能改变世界), 而公司也不能给我职业发展上面的支持, 而平时很多空闲时间, 我也没有充分利用起来. 在这里的2年是失败的. 不过我现在离职了, 算是止损了吧.

然后从今年的4月份左右, 我算是一直从事 gurudigger.com 的兼职工作, 从网站的重构到rails开始, 一直做到现在, 11月底正式加入进来. 虽然我一直从事编程工作, 但是现在才算是正式进入互联网圈了.

生活

2011年我的生活品质比以往高了一些. 至少生活中除了电脑, 网络, 游戏, 还多了很多东西.

今年决定开始练习钢琴, 花了钱上了10节课, 本来期望能够每天半个小时的练习时间, 现在慢慢地落下来了. 这个与我期望不符. 我还是决定1/1开始, 每天半小时的练习时间. 然后能练多久就多久.

锻炼身体的项目一直在草拟当中, 夏天的时候还是游过一段时间的泳, 不过现在没有坚持, 一个是锻炼身体比较枯燥, 一个就是感觉比较浪费时间. 枯燥好解决(比如从跑步换做有氧健身操), 感觉浪费时间是我观念上面的问题, 解决起来就比较麻烦了. 但是这件事情一定要开始做起来. 时间也应该是一辈子.

线下组织python定期聚会活动. 我原先是希望大家做技术的人士能够出来多聚聚. 忘记什么时候我开始号召大家出来聚会了, 我属于想清楚要做什么事情, 而这个事情需要的条件只是决定去做, 那么我就能够开始做的人. 不过后续事宜就是我的短板. python聚会算是坚持了一段时间, 不过到了后期, 因为没有考虑好如何做好运营, 不能给参与者带来价值, 一次比一次人少, 一次比一次差劲, 到最后还是只有部分骨干留下来了. 明年我觉得还是先停一段时间, 办得不好, 还不如不办.

外出旅游的话, 就 南京 有点可以说的地方. 我没有从旅游中获得太多的乐趣. 虽然因为我没有去过很多地方感到有点遗憾, 但是因为对我自己的改变不是很大, 以后旅游也不会成为我的一个高优先级项目. 当然, 还是可以作为丰富生活品质的项目.

技术领域

这一年, 算起来能够是成长的, 就是我能够用起来了rails, 以及开始做起来了前端开发. 其他方面, linux底层, 算法, tcp/ip基础, 这些都是计划要弄懂的, 结果由于我欠缺计划和执行能力而没有涨经验值, 是非常值得检讨的. 从历史上来看, 这方面我一直都欠缺, 因此浪费了大量的时间(9年), 我要在2012年好好改变这样的状况, 不然我的人生会变得非常悲惨.

我一直在考虑以后未来自己往什么方向发展, 嵌入式, 手机, 服务器后端应用, 前端. 我发现自己的兴趣点还是在作出能够给终端用户使用的产品上面, 应用性能調优, 算法架构这2个我还是比较无爱的, 未来我计划在保住后端技术基础的前提下, 发展前端, 掌握设计能力.

私生活

2011年初, 在老家的时候, 父母给我介绍了一个相亲对象. 因为我这个时候对于选择对象没有多少思路, 就抱着先交往一段时间, 深入发掘优秀点的方式谈了一段时间. 然后回到上海, 继续谈了一个月, 发现实在没有感觉, 就主动说明情况结束这样的关系. 之后好像也相亲过几次, 但是都没有进一步的发展. 然后我有尝试过其他方式的搭讪, 效果都不是很好. 然后就是朋友圈之类的方式来进行. 因为我在社交方面没有什么经验和心得, 结果也不如意.

我个人对于这方面的理论理解模型是这样的: 资源总体上是有限的(谈得起的年龄段访问是固定的), 随着时间过去, 资源总数会减少(成交了), 然后剩下来的是非合适资源(要求高过可提供的价值). 当然还有一种, 就是我个人价值增值的速度比较高, 在未来能够有更多的option, 这个我现在不太期待, 并且这方面领域经验的缺陷可能对我人生发展有阻碍.... 说得有点多了.

总体上IT男社交经验积累很慢, 对于我来说, 程序员气场很明显, 我希望能够改善这种现象, 不要让"程序员老婆都是别人挑剩下的"这样的事情发生在我身上.

现在得到一本教学书, 好好学习和练习. 合适的伴侣可遇不可求, 我不能改变概率, 但是可以增加量. 2012年要经常锻炼对应的能力, 以及投入时间, 创造更多的机会.

结论

总体上面, 我的2011年浪费了不少时间(好吧, 总是会有时间浪费的), 方向也不是很明确, 不过还是渐渐清晰起来了:

我的目标是能够设计出好的产品. 改变世界. 感兴趣的领域是能够改变最终用户的生活方式, 更感兴趣的是改变人们的学习方式(很想把理想中的大学做到网络上面, 不过没有经验没有思路).

完成这样目标需要非常多的修行, 一步步改变吧.

机械唯物主义 2012-01-01T15:40:00+00:00
rails_deploy方法之采用passenger http://blog.linjunhalida.com/article/rails_deploy方法之采用passenger

这里整理一下rails deploy的几种方法.

Passenger

首先是最简单的采用 Phusion Passenger, 现在大家都用nginx了吧, 那么下面主要还是看 passenger和nginx的配置.

首先安装passenger:

gem install passenger
    

然后安装nginx插件:

passenger-install-nginx-module
    

然后设置nginx:

http {
        passenger_root /somewhere/passenger-x.x.x;
        passenger_ruby /usr/bin/ruby;
        passenger_max_pool_size 10;
    
        gzip on;
    
        server {
            server_name www.foo.com;
            listen 80;
            root /webapps/foo/public;
            passenger_enabled on;
            passenger_use_global_queue on;
        }
    }
    

重启服务的话只要:

touch /webapps/mycook/tmp/restart.txt
    

基本上这样就可以了. passenger工作的方式还是基于多进程, 它会根据一套算法, 来计算开启多少个线程, 以及如何生成进程, 来响应用户请求.

最好要看一下 passenger_spawn_method 和 Spawning methods explained 的部分, 了解一下工作原理. Analysis and system maintenance这部分也最好看看.

不过听说passenger只是给初学者用的, 大家会用其他的可配置的工具. 比如 unicorn 等等.

这里再补充一下unicorn的使用方法, 基本上gem install unicorn, 然后执行unicorn_rails -p 8080就可以了. 在nginx上面设置一下端口转发80到8080就能用了. 这里有一个 unicorn nginx的示例 可以抄.

机械唯物主义 2011-12-21T09:32:00+00:00
为什么成人学习会变得困难 http://blog.linjunhalida.com/article/为什么成人学习会变得困难

最近和 steven yang 讨论到关于成人教育的问题. 他说他有做过一个演讲, 关于人们从学校毕业以后, 学习新的东西变得很困难. 这里是他的演讲资料.

我这里整理一下我的阅读笔记:

其中提到了三点, 关于成人教育的困难之处:

首先是观念. 当我们在某些领域掌握了一定程度的技能之后, 我们会限制住自己, 给自己打标签, 比如一个人学会了编程, 从事编程工作的时候, 就会给自己打上"程序员"的标签, 而不去考虑其他的可能性. 甚至以此作为借口, 拒绝做其他的事情.

然后就是反馈. 在学校里, 学习过程中有着无数的反馈: 阶段性的作业, 学习进度可视化, 来自他人的学习经验以及指导, 团体学习. 但是当我们进入社会的时候, 这些便利的条件都失去了. 我们的学习经历, 变得孤立起来, 我们无从得知自己的进度, 无法针对学习的困难找到帮助.

还有就是学习内容. 在学校里面, 我们所需要学习的内容会经过筛选和整理, 整体的学习曲线会变得很平缓, 每次学习的内容是有限的. 而在社会中, 在收集需要学习的内容的时候, 很容易就信息爆炸, 需要很多年才能全部掌握的知识都摆在你的面前, 并且数量繁杂, 无从下手, 这样的话, 普通人往往望而却步.

针对这几点, 有提出一些解决方案:

不要怀疑你的学习能力. 虽然学习经历可能非常困难让人望而却步, 拥有一定能够学会的信心, 是投入学习, 克服学习中遇到的困难的基础.

不要投入金钱, 而是投入注意力. 只有注意力才是学习进度提升的燃料.

采用进度作为反馈, 而不是成就. 成就(比如能够开发一个网站)在时间线上是随机的, 不好用来作为反馈的内容, 应该选用进度(比如学习了多少时间, 看了多少页的书)来作为反馈的基准.

持续学习. 学习需要长期而持续的投入, 在掌握一定阶段的知识之前, 学习成果是不稳固的. 而持续学习本身会变成习惯, 能够让坚持学习变得容易一些.

不要相信感觉. 感觉长时间没有进步, 或者感觉无法克服一个学习上的困难, 你不可能对一个你不熟悉的领域感觉正确.

以上.

机械唯物主义 2011-12-20T11:05:00+00:00