
刚看完 盗梦空间 ,佩服导演非比寻常的思路。很久没有看过这么让人头晕的电影。头晕不是因为画面的摇晃,而是我今天其实头就有点不舒服,更重要的是,我的大脑也在几何级数一样的加速运转。
我几乎同时在跟进每一个影片中的角色,他们都在不同的梦里,受到不同的制约条件,面对不同的困难,但从最上层看,他们都是变化的作用域的递归。
一切的一切都是在不同的作用域做非等价的变换
尽管死亡或者获得平衡调整感能回到上一个梦中,但其实还是付出了一定的感官代价,只是近似的等价转换。
从影片中,我看到了泛函分析,看到了函数式编程,也看到了他们的局限,这也是为什么经过变换的函数如果要变化回去,必须牺牲很多不必要的计算,以性能为代价。感谢导演 Christopher Nolan 给出这么精彩的逻辑。
最后,如果喜欢玩空间变换的朋友,强烈推荐去看一次。
我们很诚实,所以我们要先告诉你:
- 我们没有Google那种可以躺着开会的椅子,但我们有温馨舒服的员工休息空间;
- 我们没有Microsoft那种比我们会议室还大的厨房,但我们有旁边有中国各种特色美食的餐厅;
- 我们没有外企那种比学生时代还长的假期,但我们有每晚96103能叫过来的“的哥”;
- 我们没有出国旅游的福利,但我们有各种Team Building;
- 我们没有复杂的办公室文化,我们只想要真实有才的你!
我们最想告诉你的是:
- 在这里,工作很恐怖!你需要随时准备释放你的原子弹!
- 在这里,周末不会有加班,因为周末只有鬼才会来办公室!
- 在这里,我们需要制造各种工具,只有智者和勇者才可以高效的工作!
- 在这里,没有天天想着糊口的大爷,只有一群有“暴力”倾向的战士!
- 最后,我们为能突破敌人的勇士授予直接的期权奖励!
所以,如果你和我们有那么一点像:
前端高级研发工程师 Senior Front-end Developer
- 精通各种Web前端技术,包括HTML/CSS/Javascript等;
- 深刻理解Web标准,对可用性、可访问性和用户体验等相关知识有实际的了解和实践经验;
- 有基于Ajax应用开发经验,能提炼出Ajax的一些设计模式;
- 有独立设计符合公司业务的高性能框架的能力;
- 对于技术你是狂热分子,因此后端语言(Java/Ruby/Python/C),你也有所研究;
- 个性乐观开朗,逻辑性强,善于和各种背景的人合作;
- 计算机、数学、自动化等相关专业本科以上学历优先,相信学历就是一个符号。
申请此“恐怖”岗位请发简历到:jinpu.hu@qunar.com,主题注明“应聘前端高级工程师”。谢谢!!
PS:对于合适的你,我们的待遇很优厚。
今天光宇问到如果用户提交了一个表单,再点击回退按钮会保留用户之前填写的数据,他希望能重置到他最初设置的初始值。这是一个有趣的问题,我仔细的测试了常用的浏览器,目前无法解决Opera的情况,而对于ie6-8、firefox、safari、chrome都有测试,下面给出具体方法。
- 对于firefox、safari、chrome,在window的unload事件里将表单的autocomplete属性设置为off;
- 对于ie,可以使用一个很巧的判断:
!-[1,] && (function() {window.onload = function() { reset code ... };})()
判断是否为ie还可以通过ie条件注释或者'v' == '\v'
前几天一次产品需求讨论会中,公司一同学问及你觉得mac有什么高效的地方。我当时提到了keynote、提到了多点触摸、还提到了adobe的支持。其实感觉突然被问到这样的问题,一下对于mac的优势无以言表。对于我来说,mac基本就秒杀了其他竞争者。
最近有思考,怎么才是一个优秀的产品,怎么才能胜出。唯独 创新与专注 !这里提这些,那和mac有什么关系?为什么应该使用mac呢?其实我随口说出的keynote、多点触摸已经回答了答案。
Apple整个公司关注的是产品,而Microsoft等公司关注的还是技术!
你会发现一些在ibm或dell机器上跑起各种牛叉的系统的人,都喜欢称自己的机器多么的快。Gnome、KDE一些牛人是不会用的,他们要使用更加轻量级的xfce。他们更加的爱折腾自己,更加喜欢hack。这本没有什么不好,我也很喜欢折腾,喜欢hack。但我想说的是,关注的是一个或某几个技术的细节,而忽略了产品本身。其实我们最终的目标是什么?解决用户的问题。但你的机器多么的奇怪是无法直接带给用户良好的体验的,相反,我觉得这些人中的一部分,过于陶醉于自己的理想王国,过于YY了。
去听听微软的聚会,就会发现里面充满了大量的新的技术名词。.NET 、COM 、 CLR 、MFC、C#,太多太多技术名词了。而Mac的一些聚会讨论的都是keynote、safari等产品的问题。对比下ipad发布会和windows7发布会,就知道了。Steve Jobs不断演示ipad,而微软这边就不断提出很多新的技术能力。
当然mac最核心的是mac os,但我建议不要考虑做黑苹果,那无疑是会浪费你的时间,兄弟直接买一台mac吧。
很多时候不是你技术遇到了瓶颈,而是视野。
不知到大家有没有注意,编程到了一个阶段,你会发现自己把基础知识掌握得似乎很牢靠,但就是看着国外大师的作品,不断惊叹,不断惋惜,只能佩服的份。其实我觉得可能是我们的意识层面和人家的差距更多了。这里我谈一下最近的一点心得。我最近重温了下rails。Rails是一个可以高效开发web应用的基于ruby语言编写的框架。以前觉得rails的脚手架,db的操作很有创新,于是就一股脑的加入了这个阵营,还混了ruby中国的版主(比较搞笑的是后来在ruby的世界里开设了他山之石,Python版块)。但那个时候我知识被一些新奇的表象所吸引,所以很快也就转到了Python的阵营。而最近,我觉得rails才是以用户为中心设计的开发框架。我们程序员就是它的忠实用户。那些新奇的功能,都是为了给开发带来更好的体验。脚手架是快速搭建原型的一种工具、db的魔力操作是让你更加关注需求的一种支持、rspec的测试驱动,是让你明白应该tdd,tdd带来是一种软件工程的革新,只有先写测试你才会写测试,才不会漏掉你该测试的功能!特别还可以结合mac os下的growl实现很自动的测试化提示,一切的体验都太cool了。而意识到这些,未必全是使用mac带来的,但必然存在某种联系。因为只有当你每天看到更美的世界,才会觉得这个世界不够美,不是吗?人是后知后觉的。所以要不断的去使用最优秀的产品,才能设计出更好的产品来,打开你的视野,这比不断去提高某个细节的技术更加重要。
mac带来的不止美,还有哲学。
刚用mac的人会不习惯,那是因为你没有体会到它的哲学。Don’t make me think!比如默认safari打开是窗口的,很多人就想变为多标签。其实它也提供了merge窗口的功能,但实际上这正是结合四指触摸技术的时候。你可以在一个全屏的窗口看到所有的预览,不是更好的管理吗?再比如有的人觉得文件放得有点乱,没有windows下那样多个分区,每个分区自己还费力的去管理自己的目录。其实mac里,spotlight就可以光速般地在你的硬盘找到你要的任何资料,你又何必去管理呢?其实要举的例子还有很多,感兴趣的同学还可以看看高效的程序员,里面就提到过mac的很多技巧。所以,我想对拥有mac的朋友说一句,去改变你的思维,学习mac的哲学,改善你的产品的用户体验。
Continue Reading »
百度是一个伟大的公司,在这里你可以参与改变未来web的工程。简单可依赖,这是百度最核心的文化。在百度工作期间,我很荣幸先后参与并全权负责了检索页改进、用户团队、知道首页改版和开放知道等大型项目。从中我学到了怎么更好的理解pm的需求,如何更好的面对超大访问规模的网站要如何设计与编码,还学到了怎么去架构和设计一个框架,以及如何去推广它。这些都是很宝贵的经验,感谢百度提供了这样好的一个平台。
昨天,也就是2010年5月6日,星期四,整天都是很晴朗的天气,我在F3-BW瑶池宴做了百度的最后一次技术分享,我从Extjs的介绍、到与其他框架的对比,最后讲解了Extjs背后的秘密。让我更加感动的是,同学们在整个过程中不断的和我交流,思想不断的碰撞,所以最后我们聊出了很多,我感觉很尽兴,虽最近也有参加一些聚会,但这是最有感觉的一次,所有人都很积极的去想,关键不断的去表达!到最后,按竹彪的话都成了XXX批斗会。:),妙哉!
感兴趣的同学可以下载我的keynote。
再过几天,我就要离开百度了,这里我还是想再次感谢领导对我的信任与期待,我想我只有更加的努力才能不负众望。再次感谢百度可爱的同学:mingzhu、xiaoqiang、yilong、jiay、月影、jerryqu、aoao、rank、大为、多多、mbo、yunlong、yuhang、duoyi、kexin、liangdj、zengxin、cat、方荣、yubo、可恶、yangming、yuqi、tianchao、xujing、凌飞、英杰、爽哥、yankun、zhangpeng、qiaozi、shifeng、zhubiao、hsun等太多太多。
在项目中遇到了一个难题,就是非用户行为弹出窗口会被浏览器拦截,现改为用form表单提交方式,即可突破所有浏览器(在safari4、chrome、ie6-8、firefox3)的限制。
var _taction = '<{$login_callback}>';
_headaction = _taction.substring(0, _taction.indexOf('?'));
_tailaction = _taction.substring(_taction.indexOf('?') + 1);
var _name = _tailaction.substring(0, _tailaction.indexOf('='));
var _value = _tailaction.substring(_tailaction.indexOf('=') + 1);
var _FORM = document.createElement('form');
document.body.appendChild(_FORM);
_FORM.action = _headaction;
_FORM.method = 'get';
_FORM.target = '_blank';
var _input = document.createElement('input');
_input.type = 'hidden';
_input.name = _name;
_input.value = _value;
_FORM.appendChild(_input);
_input = null;
_FORM.submit();
这里有一个细节就是创建了input,那是由于浏览器会截断form提交中,action里的参数。所以这里把url中的参数动态创建hidden型的input来解决。
在弹出的窗口中可以使用window.opener来获取弹出自己的原窗口。所以我可以在弹出的新窗口做完业务后,更新原窗口。
if(window.opener) {
window.opener.location.reload(); // 刷新父亲窗口
}
/*
* 避免IE7弹出关闭窗口提示框
*/
window.opener = null;
window.open('', '_self');
window.close();
对于IE6,可以构造一个链接,触发这个链接的点击事件来达到突破浏览器阻止弹出窗口的限制,但不管怎么样都无法实现异步突破限制,也就是一旦用户行为触发了你的函数,你同步执行上面的弹出窗口代码是没有任何问题的,但如果异步的话,比如ajax或者setTimeout,那就不能保证所有的浏览器都兼容了。这个时候人品就体现了,所以平时要好好攒人品。
在Mac下一直觉得很多application都没有好的代理插件,无法实现通过指定的url跳到指定的代理,特别是使用socks5代理更不方便,除非是给所有访问设置socks5,这样很多没有被和谐的网站也绕了一个圈子。
细心观察不难发现,很多插件工具使用的是proxy.pac这个文件。什么是proxy.pac文件呢?其实它就是我们熟悉的一个纯js文件,不过有特定的格式以及预先定义好的函数,利用这些函数你就可以灵活的做模式匹配,从而实现最灵活的代理。
使用如下图:
首先你必须定义一个函数:
function FindProxyForURL(url, host) {
你要做的判断
}
函数必须返回三种固定格式的字符串中的一种,格式是这样的:return "DIRECT/PROXY/SOCKS hostname:port"
想直接无视gfw的可以直接下载我的,下载后修改PROXY变量为你指定的代理。
proxy.pac.zip
Continue Reading »
Extjs的UI组件还是很强大的,经典的checkbox树默认是不会有联动处理的。这里变量INDEX_CATEGORY_CHECKING是为了避免各个节点事件触发后的递归调用,从而解决了过多递归的问题。
'checkchange': function(node, checked){
if (!INDEX_CATEGORY_CHECKING) {
INDEX_CATEGORY_CHECKING = true;
// true时,子同父,父也同子
if (checked == true) {
node.attributes.checked = true;
// 父变为true,所有子都跟着变化
(function(node) {
var _this = arguments.callee;
if (!node.isLeaf()) {
node.expand();
node.eachChild(function(child) {
child.ui.toggleCheck(true);
child.attributes.checked = true;
_this.call(_this, child);
});
}
})(node);
// 父变为true,父的父(如果有的话)也应该都为true
(function(node) {
var _this = arguments.callee;
if (node.parentNode && node.parentNode != t.root) {
var pnode = node.parentNode;
pnode.ui.toggleCheck(true);
pnode.attributes.checked = true;
_this.call(_this, pnode);
}
})(node);
} else { // false 时,子同父,但父不一定同子
node.attributes.checked = false;
// 父变为false,所有子跟着变化
(function(node) {
var _this = arguments.callee;
if (!node.isLeaf()) {
node.expand();
node.eachChild(function(child) {
child.ui.toggleCheck(false);
child.attributes.checked = false;
_this.call(_this, child);
});
}
})(node);
// 父变为false,但父的父(如果有的话)不一定变化
(function(node) {
var _this = arguments.callee;
if (node.parentNode && node.parentNode != t.root) {
var pnode = node.parentNode;
var chk = false;
pnode.eachChild(function(child) {
if (child.attributes.checked == true) {
chk = true;
return false;
}
});
if (chk == true) {
return;
} else {
pnode.ui.toggleCheck(false);
pnode.attributes.checked = false;
_this.call(_this, pnode);
}
}
})(node);
}
INDEX_CATEGORY_CHECKING = false;
}
}
最近爱民在大谈架构,玉伯兄也发表了他的看法,其实我也思考了良久,他们俩的演讲和文章让我受益良多,于是也写写吧。
在中国古典建筑学中,架指的是范围;而构是构件,古时多为古构架,也就是在一定范围,用很多木头做的构件(连接件)相互连接,到达最终的建筑物。
那么架构就是约定的系统范围以及系统的组成模块中的这些连接件。
那做一个好的设计就必须从原始需求,抽象出最终的目的,从而约束好系统范围与指定系统各模块中的连接件。
之所以说要抽象出最终的目的,是由于人的语言表达,很多时候只能进行表层表述,也就是描述的需求可能是很粗的,而在冰山之下,才是最终的目的。这是一个优 秀的架构师应该去分析与抽象出的。
打一个比方,A说想下载狮子座,而如果架构师就认为A是要下载这个功能以及狮子座这个歌曲,那就太粗了。很有可能A的需求是想听一下狮子座,而A的潜意识 里要下载才能听,其实给出一个百度mp3在线试听的链接也就能满足了A的需求,而且试听界面还有曾亦可的其他歌曲,很有可能超越用户的期望,从而给出惊 喜。
那要抽象到什么层次才是对的?其实这就是一个适度的问题。之所以有了很多开源框架,各企业还是要不断的制造自己的轮子,除了有不正常的考虑,更多的是出于 对自身业务的合适。所以做架构的首要问题,就是要弄清楚当前的问题状态?也就是当前要解决问题所能提供的资源以及最终期望的程度。
比如我们经常提到的栅格系统,对于不断制作风格各异的专题页面的部门,那这个架构就是无意义的,或者是架构师自己YY的产物。他不适合。问题根本就不需要 抽象到把一个网页分成N(N>24)个列,制作一些通用的元素库和效果脚本这就是合适的架构。而对于一个大的门户,由于各功能模块相对布局稳定,那 抽象到栅格系统这个层次就很适合了。
而约束好系统的范围之所以我如此强调,究其根本就是,没有范围,或者范围不清楚就会让设计师、程序员漫无边际的思考和行动,浪费的是大家的时间和精力。比 方,如果没有给一个笔筒限定范围,那就可能制作出一个垃圾桶,结果就是个玩笑了。
最后说下连接件,连接件在软件中可以表现为接口及其实现。我们说实现是细节,而指导细节的是接口,也就是标准。在一个架构设计中,什么是要细化的?其实应 该想好有些什么接口。定好了接口,也就是明白了要细化的工作范围。这里再强调一次,架构是一个由粗到细的过程,细就是细在接口实现上,而对于没有接口的实 现,其实就是属于额外的枝节了,应当在项目中最先砍掉。
我再做一个比方,我们要一个放置笔的东西。这是目的,可能我最初的需求也许是要一个笔筒(但笔筒这个词发明以前,谁也不知道笔筒是什么东西)。那如果最终 有一个类似杯子一样的东西给用户,那这个杯子的把手是不是过度设计?不是!因为接口设计中,我们有定义笔筒可以被拿,至于传统的笔筒一直是没有把手的,与 加一个把手的杯子做笔筒,这是没有超出接口定义的,这个细节的增加是合理的。那如果是一个高级太空杯,也就是有盖的一个水壶。那问题来了,如果笔很长,那 就无法盖上水壶的盖子,也就是笔筒被盖这个动作是先前没有被定义的。那这就是过度设计,就是项目中的枝节(也许未来有益),一般需要砍掉。
文章写到这里,其实内心还有很多想法,一下子无法表达,也许项目太紧,暂时也不够进一步思考的时间,将来想好了,再加到这里,所以目前这篇文章还是未完待续。
这是我以前写的一篇文章,最近我在博客上不是推荐了OpenResty吗?发现很多人还不理解Rest的概念,所以放到这里,希望对大家有益。
首先说下什么是REST,这个四个字母是Representational State Transfer的简写,它是一套设计原则:表示性状态转移。接着我们再看下Web背后的暗藏的设计理念和传统的Web服务(RPC式的)的差别:
Continue Reading »