My Tool Chain Part2

开篇先吐一槽:上一篇的名字就起的不对,明明该叫My Tool Kit,然而脑袋一抽写成了Tool Chain。结果回过头再读一遍,着实想不到就那几个tool要怎么才能凑个chain出来。

算了,看在命名的连贯性上,继续错下去好了:

Sublime

这次写插件:

Package Control

没这个玩意,就不用谈插件了。只说一个良好的体验——这个插件带了Enable/Disable和Remove/Install两组功能,意义在于——后悔的时候不用再去下载,前提是用不上的时候,你不会冲动的先删为敬。

Evernote

本来该是一个H3,但大部分时候我用Evernote都是在Sublime里使用,所以放在这一级写也没有什么不妥。

首先,你得承认,你还是需要一个云笔记应用的,因为现在我们能用到/必须用到的端确实是越来越多了。

那么墙内可选的,稳定+大牌的产品就只有有道云笔记和印象笔记了。有道云笔记试用了一下体验也还不错,特别是内容直接支持markdown这个特性,简直是programmer-friendly。

只是,有道没有提醒功能!根据搜索引擎的历史,似乎之前的版本是提醒功能的,不知为何现在的版本砍掉了这个功能。这就蛋疼了,要知道我在手机上的使用场景,一半都是提醒相关的(并不想用闹钟,我就想要all in one的note)。

在pc和mac上,你就需要Evernote这个插件了。本地生成一个key文件,由插件帮你使用(封装&隐藏)Evernote官方提供的web API,就直接可以read和write你的所有笔记和笔记本了。笔记内容支持markdown编辑,而同一份笔记在移动端/网页端/官方客户端查看的时候则是html。

然后,这套note就完全符合我的需求了:能便捷输入的时候(有键盘),可以更好的格式化和编辑内容;不能便捷输入的时候(移动端),只要直观的查看,而且能添加定时提醒。

最后,一点启示:要做大平台,web API真的只是标配

Hex Viewer

我不想装ultra editor,我有时候需要直接查看二进制,就只能依靠这个插件了。

Markdown Preview

用了一段时间的Markdown Editing,发现并不是很喜欢那种“半所见即所得式”的模式。我多半时间只是想要基本写完了看下最后的效果罢了,所以这个只需要一个命令在浏览器中看到最后效果的插件就很适合我了。

良心的是,这插件还专门提供了输出成Github Style的选项。



其他杂七杂八的插件,多数都是一些语言相关的语法增强和格式化的工具,没什么好说的,用到时候去下个最热门download最多的就好。

虽然将来可能会被VS Code取代(3~5 yrs i guess),但现在sublime确实还是我的文本编辑器首选。


docker

不管其他人怎么吹docker(docker是真的吊,我懂),对我来说docker就只是个工具,是我们这种“低端懒鬼型”程序员的救命神器。

最近装个deeplearning处理图像的应用,断断续续装了我一个礼拜你敢信?当然网络问题是最大的锅,但各种dependency的issue也是足够让人头痛。

我真的就只是想要binary罢了,我真不相信我的环境特殊到独一无二啥都要我自己build。

以前倒是真的干过为了玩某个linux上的东西下了一整个虚拟机的镜像的事,事后感觉就像是为了吃KFC的番茄酱买了个全家桶似得。

既然能虚拟化一个Runtime,何苦要去虚拟化整个OS?这正是docker厉害的地方,强就强在这个概念了!(似乎docker不是最先提container这个概念的,不过能炒到最火也是一种能力啊)

反正就效果来说,我想玩一下Jenkins什么的,再也不用去step1step2step99(我丝毫不关心你的依赖,也不关心makefile是怎么写的,真的),也不用去下虚拟机镜像了。我只需要优雅的打开我的docker,高贵的在docker hub上搜索一下,然后冷艳的等待下载启动container,最后,开整!

小小的自来水一发daocloud,免费提供墙内的镜像和加速,自然是极好的。


revealjs

简单概括就一句话:用markdown做基于浏览器的ppt。

只要是程序员,上手都会很快。最后的效果还不算太差,大部分的场景绝对都足以应对了。

如果你想,revealjs也能做到跟powerpoint一样支持演讲者视图,只是要就用到nodejs了,麻烦了不少。

我自己也fork了一个直接clone了就能开干的版本

END

谁说UV只能<1

先说结论:UV在实际应用中并不一定小于1,OpenGl对texture进行采样的时候,专门有一个参数来控制对UV坐标大于1的部分如何处理——详见这个链接的wrapping部分。

也就是说,对于obj文件:

v  -44.036751 0.000000 47.681671
v  42.139252 0.000000 47.681671
v  -44.036751 0.000000 -38.494034
v  42.139252 0.000000 -38.494034
# 4 vertices

vt  0.0 0.0 0
vt  2.0 0.0 0
vt  0.0 2.0 0
vt  2.0 2.0 0
# 4 texture vertices

vn  0.000000 1.000000 -0.000000
vn  0.000000 1.000000 -0.000000
vn  0.000000 1.000000 -0.000000
vn  0.000000 1.000000 -0.000000
# 4 vertex normals

g Plane01
s 1
f 3/3/3 1/1/1 2/2/2 4/4/4

g

如果用GL_REPEAT来对材质采样并渲染模型,会得到一个垂直于Y轴的平面(四个v坐标很容看出来),且对应材质会均匀的平铺四次(vt刚好是(0,1)的两倍),如下图:

2x2

对应在u3d中,只要把texture的wrap mode设为repeat就行(还有一个选项是clamp,实际对应的是GL_CLAMP_TO_EDGE)。

事实证明,0 < UV < 1这个定义永远成立只是我一厢情愿的想法罢了,在实际应用当中,UV > 1恰恰是个解决repeat问题的最佳方案。不过这个方案还是存在缺陷的——需要repeated的材质无法跟其他材质一起打成atlas了。

又涨姿势了。

END

The Good Code

回家在XP上写东西,惊喜的发现连国产软件也都开始嫌弃和逐渐放弃XP和IE了。恩,慢归慢,只要不倒车,车轮总还是向前走的。

技术总是在飞速的更新。但无论技术怎么革新、新概念如何吹嘘,一行行的源代码始终是整个软件生态系统中最重要的根基。就像猎命师靠收命格,海贼靠热血,绝地武士靠原力,写代码才是程序员安身立命之本。

写了差不多五年代码,多多少少能沉淀一点跟《Clean Code》和《Refactoring》不太一样的东西了。

一记:

read more

Functional Thinking

标题起得有点大。

说不上来到底是幸运还是不幸,总之就是年底有空超前完成了一下明年的KPI——Learning Haskell。完成度还算满意,就连传说中的monad也算是有个感性的认识了。

强推这个教程,基本上是我所有看过的教程里最良心的了。

第一次听说Functional Programming还是好几年前刚刚开始写代码营生的时候,那时的我还是初级代码搬运工,冷不丁搬运到了.Where(=>).Select(=>).ToArray()这种第一眼看不明白多看两眼又觉得好厉害的代码,瞬间就惊为天人。这好几个for都写不出来的代码,一个chain就做完了。顺手多google了一下linq的东西,也就无可避免的学到了一个新单词——Functional Programming

平凡人类认知那些first impression不错新事物,大多会经历从overestimate到underestimate的一个或多个反复。反正我对C#中的linq的认知是经历了“linq == silver bullet”和“linq == performance hit”的起伏的,现如今再看,当然是能明白具体问题具体分析才是重点,只是写过的那些代码里就不免一时都是linq又一时连using System.Linq都不见。

不过对于FP的好感一直是有,一是因为不懂,二是因为直观看来代码确实精简。这两年给自己安排的KPI都是FP相关的(去年是lisp,今年的lua相关性弱一点,之后的haskell可是自喻为pure FP呢),嗯,这叫IDL(Interest Driven Learning)。

今年眼看就要结束,总算是能沉淀一些在我看来能算作是Thinking的东西,还挺好的。

read more

Reading Lua (1) 准备工作

如果说后面几篇对lua源码的分析是干货的话,这一篇应该可以说是“废话”了。但事实上,看完了这篇,后面几篇你都不用看了。
因为这一篇跟后面几篇的关系——简单来说就是——渔和鱼。
在这一篇,我只写自己是怎样读代码的,而不提具体的代码。之所以把自己<b>了,是想要强调此处的渔是非常主观和个人化的东西,必须不适合所有人,就权当自己的经验总结和采坑大全了。

想要来一顿美味的Lua源码阅读大餐,你需要准备以下食材:

  1. 一个Visual Studio (不是说GDB不好,只是在断点的时候直接就转到上下文中函数的定义或实现,这种体验谁用谁知道)
  2. 一份原汁原味的Lua5.1.4源代码(这个版本可参考的资料最多,虽然Lua各种总的loc都不多,但简单而完备的版本看起来肯定更爽)
  3. 各种参考资料适量(云风的GC系列文章、ANoFrillsIntroToLua51VMInstructions、Mike Paul在各种地方留下的阅读指引)
  4. 足量的耐心
  5. 足量的时间

有了以上几种食材,烹饪的过程就异常简单了——F5!

没错,是他,是他,就是他:

F5

跟广为流传的MikePaul推荐的Reading Order不同的是,我觉得还是一上来就F5靠谱的多。默念函数名也是读F10也是读,running code总是比plain code更生动易懂(还有一种可能是我水平太low,大神都是可以直接通读脑中构建running state的上下文的)。当然,所谓“F5读代码大法”,并不是直接在main的第一行打上一个断点以后就不停的F10F11就行了。而是要在了解源代码大体结构(下一篇具体来写)的基础上:

  1. 确定一个feature
  2. 根据初读代码和猜测(怎么猜?靠函数名和变量名呗),在大致的位置打上断点
  3. 构造Lua代码
  4. 观察程序是不是会跑到这个断点
  5. 验证feature,整理整个流程

For example: 我想研究Lua的GC,看文章,大致Scan代码,发现GC是分好几个步骤的比如GCSsweepstringGCSsweep,那么当垃圾不包含string的时候,在一次GC里还会执行GCSsweepstring这个步骤吗?

构造lua代码如下:

local foo = {}
for i=1,1000 do
	foo[i/10] = { a = i, b = i+1 }
end

断点当然是打在lgc.c的这个位置:

	case GCSsweepstring: {
		lu_mem old = g->totalbytes;
		sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);

然后,F5走起。到断点了么?Callstack是什么样的?LuaState相关的field都是怎样的?解答自己的疑惑,再不停发问,继续解答。如此递归,就离这道大餐上桌的时间不远了。

一些PS:

  • VS中的Compile as C Code或者Command Argument怎么设置,google一下就知道
  • 宏没法打断点,实在搞不懂里面的实现就只能手动inline了,记得ctrl+z回来就好,虽然不改回来也没什么大问题
  • 接上一条,大胆的改代码做实验写注释,弄坏重新下一份源代码就好
END

Reading Lua (0)

跟去年的Learning Lisp遥相呼应,作为今年自我KPI完成的总结文来写,这次逼格高点,第一次在Blog写个series。

计划的Content Table如下:

  1. 准备工作
  2. 代码结构
  3. Lua有AST么
  4. 此VM非彼VM
  5. GC
  6. TODO

还有一些泛泛的感悟,放在这一篇抒发比较合适:

Lua的源代码写的太DIAO了!Lua的源代码写的太DIAO了!Lua的源代码写的太DIAO了!重要的事情说三遍。跟原来读了好多次都没读下去的Ruby源代码不一样,一共就50+的文件和20000W左右注释详细结构清晰的CodeBase,给人心里压力小太多了。虽然语言的复杂程度不是一个量级的,但麻雀虽小五脏俱全,Lua作为一门完美实现了设计初衷的语言,代码肯定是同样值得一读的。
Lua的实现没有任何依赖,而是用的是纯的Ansi-C!终于不用在Mac上make了,终于在Windows上也能out-of-the-box的跑起来了,对我们这种Windows低端程序员来说——太!开!心!了!
指针对我们这种低端程序员来说还是好难,虽然终究能看懂,但是花时间略久。Macro虽然写的很花哨,但我会手动inline,所以也还好。

END

Remove Vs RemoveAll

有个feature需要比较高频率的从集合中移除一部分元素,稍微脑洞了一下,感觉用for-loop+Remove应该比RemoveAll要快(可能是RemoveAll的example里用了lambda,影响了判断)。

BUT,test dont lie,写了个测试试了下:

var list = new List<int>();
for (int i = 0; i < 1000; i++)
{
    list.Add(i % 3);
}

var iter = 1000;

Profile("Remove", iter, () => 
{
    var l = list.ToList();

    for (int i = l.Count - 1; i > -1; i--)
    {
        if (l[i] == 0)
        {
            l.RemoveAt(i);
        }
    }
});

Profile("Remove All", iter, () => 
{
    var l = list.ToList();

    l.RemoveAll(item => item == 0);
});

结果RemoveAll效率要比Remove高好几倍,找了源代码扫了一下:RemoveAllO(n)且只有一次Array.ClearRemoveAt却每次都要Array.Copy(压缩空隙的操作),结果显而易见。严格来说,我是在Unity做的测试,但读的是.Net的源代码,好像有点不严谨

So,Once More:Test dont lie,Code dont lie。

END

My Tool Chain

timediff(now, lastpost).month > 6

这半年其实收获良多,各种language和各种runtime加上各种platform玩来玩去,想写的能写的值得一写也挺多,不急,慢慢来,记着就好。

念念不忘,必有回响。再拖拉我还是会写

这篇的主题是ToolChain——也可以叫——当我重装Windows/Mac时我弄些什么。

Alfred/Launchy

Alfred已经太有名了,无需多言。在windows上我能找到的(用过的)最好的替代品就是Launchy了。
实话实说,win7点了win键以后输入程序名相对xp来说已经有了很大提升了,但比起launchy这种专业的软件来说还是差了一大截。
特别是可以自定义程序搜索路径和记住最近打开的程序(e.g:我现在alt+space | c就是conemu,alt+space | ch就是chrome,alt+space | u就是unity)这两个feature,真心好用。
关于这种全局快捷键app的必要性,上古大神Alan Kay(可能记错)就说过:newbie用鼠标,frequent user用快键盘+鼠标,pro只用键盘。不用鼠标带来的效率逼格可以详询*nix over Windows党。
最后再说一个Launchy的好:donate只要2$,对比起sublime的70$(我觉得sublime也很好,但是没有好到35倍 || 如果我的工资发的不是¥而是$我就买),就是买买买啊。

Chrome

也算做过一段时间的web开发,各种浏览器出于工作也好个人喜好也罢,都用过一圈了,最后还是觉得Chrome最顺手(这类软件没有什么最好,只有最顺手)。
好像原来的原来还写过firefox plugin的post,插件这玩意也就是锦上添花,firefox现在跟Chrome比已经算不上了。
具体的有多就不表了,现在必须的只有手势这一朵了(还是稍微一提:Chrome的帐号系统确实好用,至少不用像以前的firefox一样每次重装都折腾一次插件了)。

VisualStudio/Sublime

Visual Studio出了community版本以后,Windows上最强的IDE基本就没任何争议了,随着MS越来越拥抱开源,其在社区里的口碑也越来越好了,现在我黑MS的欲望都越来越弱了。
Sublime作为Mac/Windows上都通用的Editor,对于我们这类小白开发(大神的Vi/Emacs都是比VS还厉害难用的多呢),着实是比其他文本编辑器好用了一大截。
这两个共同的优点就是1.feature多 2.插件多 3.GUI功能也很好用。诚然用鼠标的效率比不上用键盘,但鼠标悬停显示各种变量怎么也比用printpp让人愉快很多吧。

Python/Ruby/Github

Python和Ruby优先级高于其他运行时(Mac预装了)的原因在于很多小工具都是基于这两个runtime的,其他lua lisp node什么的就看心情了。关于ruby gem有个小tips:

gem sources --remove https://rubygems.org/    
gem sources -a https://ruby.taobao.org/    
gem sources -l

必须要赞一下taobao,在国内的开源界确实比其他公司走的要早要远。
Github for Windows这个GUI我觉得比tortoise还要好用,for Mac就更不用说了,Mac能战的SVN GUI根本就没有。

ConEnu

在Windows下——支持tab页+自定义font+支持ctrlc+ctrlv+最大化窗口的命令行工具——就我用过的——只此一家,所以没得选了。

What’s More

TODO

END

Learning Lisp

(MEMBER `TRY `(DO DO-NOT))

QQ签名从["do","do not"].include? "try"改成了上面的,眼看今年给自己的KPI——learning a language every year完成在即,心情大好。感觉自己编程功力又上升了一个小段位,下半年剩下的时间好好啃下SICP (看亚马逊评论说中文翻译的不太好,看来又只有原版走起了),争取能给自己打个S。

Lisp,逼格最高的编程语言之一(比他逼格更高的没人出来炫耀,比他逼格低的那就太多了)。在没TRY过之前,我觉得我肯定也是DO-NOT了。好好看了下,发现对我们这些C语系出身的程序员来说,Lisp真心可以算的上是mind-blowing了。极简的规则(上面那个quote已经包含了Lisp语法中所有最基本的元素了),一切都是list,而一切又都是执行(evaluating)。道生一,这似乎在哲学上更容易生出万物,也更有道法自然的感觉。

对lisp理解还停留在感性层面,道的出的牛逼也只有上面这些了。

Talk is cheap, show me the code。我懂,这个repo里有四个版本(Lisp Javascript Ruby C#)的代码,都只在干一件事情——计算一个多层嵌套的数组的和。先只贴Lisp的版本出来:

(DEFVAR *L* `(1 2 3 (1 (2 3))))

(DEFUN SUM-ALL (LIST)
       (COND ((ENDP LIST) 0)
             ((NUMBERP (FIRST LIST))
              		(+ (FIRST LIST) (SUM-ALL (REST LIST))))
             (T (+ (SUM-ALL (FIRST LIST)) (SUM-ALL (REST LIST))))))

(SUM-ALL *L*)

这段简单的递归能很好的体现出Lisp的表现力。平心而论,对于C#这种不支持异构数组的强类型语言来说,这对比似乎不怎么公平,因为C#版本里很大部分篇幅都用来构造数组了。而且递归这种东西好像本来就是从Lisp来的,写递归函数不就是在扬长避短么。对于你们这种怀疑我专门用特别的实例厚此薄彼的行为,我只想说,泥垢了

再次总结一下,现阶段Lisp于我来说炫酷得没朋友的特性就两点:极简的定义&&自顶向下的表现力。

PS1:入门看的是德国某大学的Common Lisp的在线教程,整个课程的设计简直是良心,还有statistic:

learn_lisp_statistic

PS2:Lisp的方言选择也是装逼活门艺术,以后就用Scheme了。我又不需要practical(我的武器库很牛逼,不要惹我),Common Lisp对我来说就太大了点。

SICP我来了。

END

Embedding Mono

前后折腾了好几天,终于把Demo跑起来了,全部的代码见这个repo,虽然行数不多,基本意思算是表达的比较清楚了(cpp里的注释都用心在写了,在我大Windows上跑起来的方法见上一篇post)。在天天用.NET的时期找了各种借口一直都没好好研究过hosting,这次用Mono做了个demo,算是把这个念想给圆了。

嗯,念念不忘,必有回响。

心得我只捡重要的,一个OL说完好了:

  1. 学好C很重要,不看Linux (实际上是看不懂),看个ruby mono什么的还是需要的。还是觉得#define什么的好难懂,想吐槽都不知道从何吐起。
  2. 对比unity的MonoBehavior,觉得我的Lib的设计更合理啊!毕竟virtual不就是干这个的吗,而且,在子类写完override就能出智能提示也要比光靠记忆去写Start()更科学啊。unity这样设计,应该是出于简单的考虑(这性能的提升可以忽略不计吧)?

  3. 在unmanaged的环境里去找method其实跟在managed环境里用反射做的事情和做的结果都挺相似的,当然,如果有很多假设(custom code的命名方式命名规则等等),就会少了很多读metadata的麻烦事儿。

  4. 设计framework/library确实比application要难得多,抽象和设计的重要性/关键性是做application比不了的。

  5. 开源就是好,你在想知道细节的时候可以去看,而不是猜。

  6. unity studio更像是photoshop而不是visual studio,没的辩。unity用mono做script engine也就是看上了它的跨平台而已,如果ruby python什么的跨平台做的足够好,可能也轮不到mono了。

做这个Demo感觉经验值涨了不少,不过还是要过两天用build on mono的形式写个一样功能的Demo,才算圆满。

END

为啥Unity3d没xx.designer.cs

winform时代,在vs的designer里拖啊拖啊,总是可以自动生成一个designer.cs,够(xiang)叼(si)的话你还能自己去改designer里的代码,运气好了vs的designer还能正常的识别,然后再继续拖拖拖。

unity3d的designer没有生成.cs,简直是,耍!流!氓!

先猜个原因再来做点实验:

前方高能预警(纯YY向)

read more

Callbacks 和(han) Promise 和 Rx*

想想还有几个月就去台湾了,心里还有点小激动呢,标题卖个萌。


回头看了一下,发现自己最近几个月对callback和async这些玩意儿出奇的关心。原因无它,各种callback和async操作实在是太反 人 类了(此处人类特指地球上某统治级灵长类生物中跟其祖先最接近的一群——程序猿,BTW,反正都扯蛋了就多扯两句:人人都知道user-friendly重要,但却没有人比微软更注重programmer-friendly,就这一点,简直要为M$点赞,以后蛋疼了一定要写一篇关于大微软爱护程序员的软文),而如何抽象这些反人类的东西,正是计算机和编程领域里最有魅力的部分。

read more

六月七日

写点啥

正好六月七号,按高考作文的套路来——总分总,记叙文,安全牌,力保上40。

总:莫忘初心,莫失匠心。

分:对不住,语文老师,我要开始散文了。

read more

无论如何,id还是比class快

http://jsperf.com/queryselector-id-vs-class

虽然这种结论用小脚趾头想也能得出来,还是jsperf了一下,92%的slower还是挺出乎意料的,基本上就跟sql有索引和没索引的差距一样大了(其实应该原理也类似才对)

END

不作死就不会死——重装OS X记

不作死就不会死,简直真理。

一个新的MBA,被我折腾了一天时间,直接就变成砖头了……

read more