Atomatom 自动补全全<p>标签怎么不换行

我的换行方法是&br&左大括号左边有换行符&br&左大括号右边有换行符&br&右大括号左边有换行符&br&右大括号右边有换行符&br&&br&有些人的不换行的方法是&br&左大括号左边没有换行符&br&左大括号右边有换行符&br&右大括号左边有换行符&br&右大括号右边有换行符&br&&br&一点都不对称,这个人写出来的程序肯定不能看。正确的不换行的方法,当然是要对称的:&br&左大括号左边没有换行符&br&左大括号右边有换行符&br&右大括号左边有换行符&br&右大括号右边没有换行符&br&!
我的换行方法是 左大括号左边有换行符 左大括号右边有换行符 右大括号左边有换行符 右大括号右边有换行符 有些人的不换行的方法是 左大括号左边没有换行符 左大括号右边有换行符 右大括号左边有换行符 右大括号右边有换行符 一点都不对称,这个人写出来的程…
&img src=&/a66659f53edc109fb7acfee_b.png& data-rawwidth=&598& data-rawheight=&312& class=&origin_image zh-lightbox-thumb& width=&598& data-original=&/a66659f53edc109fb7acfee_r.png&&&br&我一般都这么写 & _ &&br&另外我最喜欢 lAtEx 了。&br&&br&= = = = = =&br&其实,我是偏好不换行的。&br&&b&#1 经常使用的语言(JavaScript)提倡不换行的风格。&/b&&br&原因参见:&br&[1]: &a href=&///?target=http%3A///subject/3590768/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript语言精粹 (豆瓣)&i class=&icon-external&&&/i&&/a&&br&[2]: &a href=&///?target=http%3A///blog/2012/04/javascript_programming_style.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Javascript编程风格&i class=&icon-external&&&/i&&/a&&br&&br&&b&#2 在保证一致性的情况下,代码冗余度更小。&/b&&br&例如: if else 语句的&u&一致性&/u&&br&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&c1&&// Bad!&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&foo&/span& &span class=&o&&&&/span& &span class=&nx&&bar&/span&&span class=&p&&)&/span&
&span class=&nx&&foobar&/span&&span class=&p&&();&/span&
&span class=&c1&&// Good~&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&foo&/span& &span class=&o&&&&/span& &span class=&nx&&bar&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&foobar&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&原因:与花括号中包裹的语句不只一个的情况保持一致,也方便后期添加语句。&br&在保持以上的一致性的情况下,对比换行和不换行的写法&br&&div class=&highlight&&&pre&&code class=&language-text&&// 换行
if (foobar)
if (foobar) {
&/code&&/pre&&/div&很明显不换行更加紧凑,冗余的行数要少。&br&&br&&b&#3 原子性&/b&&br&和上面的例子一样,单看 else 部分&br&换行的写法:&br&&div class=&highlight&&&pre&&code class=&language-text&&...
&/code&&/pre&&/div&不换行的写法:&br&&div class=&highlight&&&pre&&code class=&language-text&&...
&/code&&/pre&&/div&不换行的写法中,else 的过渡语句占了三行,在这三行间的空隙中插入任意一段语句,原来的代码都不能正常工作。而不换行的版本,一行却是一个原子性的整体。&br&&br&&b&#4 视觉流不会被冲断&/b&&br&如果花括号换行,视觉流在第一个 '{' 时 被冲断一次,到了 else 时理应被冲断一次,结果被冲断了三次。&br&&img src=&/1bf668b2f0e_b.png& data-rawwidth=&236& data-rawheight=&416& class=&content_image& width=&236&&&br&对比不换行的&br&&img src=&/f5c65604baecd4923a6ffd_b.png& data-rawwidth=&214& data-rawheight=&368& class=&content_image& width=&214&&&br&代码块被清晰的切分成两块,一刀不多,一刀不少。&br&&br&&b&最后的话&/b&&br&选择什么代码风格,第一个要考虑的是别人,而不是自己。如果使用这种语言的人,大多采用这种风格,那么就优先使用这种风格。如果是项目规定需要遵守的规范,那就更应当遵守了。&br&至于换行不换行、孰优孰劣见仁见智。我虽然喜欢不换行,但如果让我去写 C# 这种规范要求换行的语言,我也会义无反顾的换行。&br&&br&(另外,知乎编辑器真是渣到爆 & _ & )
我一般都这么写 & _ & 另外我最喜欢 lAtEx 了。 = = = = = = 其实,我是偏好不换行的。 #1 经常使用的语言(JavaScript)提倡不换行的风格。 原因参见: [1]:
#2 在保证一致性的情况下,代码冗余度更小。…
1、Python做数据挖掘很强大,最近几年很火的机器学习以及较为前沿的自然语言处理也会选用Python作为基础工具。下面是我之前写的一点Python数分挖掘的简单案例,代码均有,可以看下:&a href=&/question//answer/& class=&internal&&你用 Python 做过什么有趣的数据挖掘/分析项目? - 据数的回答&/a&
写的简单且乱,轻拍!&br&&br&2、楼主提到Python作图,提到了matplotlib库。其实楼主可以试一下seaborn,简单易上手而且结果美观:&br&&blockquote&Seaborn&p&Matplotlib是Python主要的绘图库。但是,我不建议你直接使用它,原因与开始不推荐你使用NumPy是一样的。虽然Matplotlib很强大,它本身就很复杂,你的图经过大量的调整才能变精致。因此,作为替代,我推荐你一开始使用Seaborn。Seaborn本质上使用Matplotlib作为核心库(就像Pandas对NumPy一样)。我将简短地描述下seaborn的优点。具体来说,它可以:&/p&&ol&&li&默认情况下就能创建赏心悦目的图表。(只有一点,默认不是&a href=&///?target=https%3A//jakevdp.github.io/blog//how-bad-is-your-colormap/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jet colormap&i class=&icon-external&&&/i&&/a&)&/li&&li&创建具有统计意义的图&/li&&li&能理解pandas的DataFrame类型,所以它们一起可以很好地工作。&/li&&/ol&&/blockquote&上述引用来源:&a href=&///?target=http%3A///80853/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Python和数据科学的起步指南&i class=&icon-external&&&/i&&/a&&br&&br&一两行代码就可以做出类似下面的图:&br&&img src=&/0b5ee6d551_b.png& data-rawwidth=&546& data-rawheight=&533& class=&origin_image zh-lightbox-thumb& width=&546& data-original=&/0b5ee6d551_r.png&&&br&&b&详细学习资料可查看:&a href=&///?target=http%3A//web.stanford.edu/%7Emwaskom/software/seaborn/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Seaborn: statistical data visualization&i class=&icon-external&&&/i&&/a&&/b&&br&&a href=&///?target=https%3A//pypi.python.org/pypi/seaborn/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&pypi.python.org/pypi/se&/span&&span class=&invisible&&aborn/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&&br&3、本科能否从事数据挖掘这个就难说了。如果楼主聪明好学,数学+统计基础不错,而且有一定编程能力,再加上上学期间找一些相关的数据挖掘实习练习一些项目,这样很大概率是可以的!或者楼主虽是本科,但是有较好的学校专业背景,那也是可以的! 其它情况不敢保证!&br&&br&&br&&b&以上!仅供参考!&/b&
1、Python做数据挖掘很强大,最近几年很火的机器学习以及较为前沿的自然语言处理也会选用Python作为基础工具。下面是我之前写的一点Python数分挖掘的简单案例,代码均有,可以看下: 写的简单且…
我不喜欢提问里的说法。&br&&br&学科教育的狭隘性?知识的结构性缺陷造成问题?那么请问,什么是结构性缺陷?我们都从基础教育过来,基础学科中包含的物理、化学、语文之类的课程,我们一概不少。如果说是后来的专业分家导致的区别,那么哪一个科目都有取舍,我们谁也不干净。&br&&br&那么究竟提问者质疑的是什么?品性?世界观?价值观?好吧,我们就来一个个看看。&br&&br&=== 品性?===&br&&a class=&member_mention& data-hash=&461de99bf9c5ee3c71b375c& href=&///people/461de99bf9c5ee3c71b375c& data-hovercard=&p$b$461de99bf9c5ee3c71b375c&&@王亞暉&/a& 答案中说 Perl 程序员的三大美德是:懒惰、缺乏耐心和自傲(Laziness, Impatience and Hubris)。这话是很流行,但实际上 Perl 之父 Larry Wall 曾经同样提出,程序员美德的真实含义是:勤勉、耐心和谦恭。这篇事实上在黑客圈子里同样著名的文章,《勤勉、耐心和谦恭》,收录于O'Reilly 的《开源软件文集》中。看到了么?先生们女士们,你们未必真的看懂了程序员想说的话。&br&&br&=== 世界观?===&br&毫无疑问地,程序员的思维方式和艺术家可能很不同,至少文学家和画家不会把如下的一段括号套括号的物事看作一种美,但 Lisp 程序员们则因为其用 Lisp 语法描述了 Lisp 的解释过程而欢欣鼓舞。&blockquote&(defun eval. (e a)
((atom e) (assoc. e a))
((atom (car e))
((eq (car e) 'quote) (cadr e))
((eq (car e) 'atom)
(eval. (cadr e) a)))
((eq (car e) 'eq)
(eval. (cadr e) a)
(eval. (caddr e) a)))
((eq (car e) 'car)
(eval. (cadr e) a)))
((eq (car e) 'cdr)
(eval. (cadr e) a)))
((eq (car e) 'cons)
(eval. (cadr e) a)
(eval. (caddr e) a)))
((eq (car e) 'cond)
(evcon. (cdr e) a))
('t (eval. (cons (assoc. (car e) a)
((eq (caar e) 'label)
(eval. (cons (caddar e) (cdr e))
(cons (list (cadar e) (car e)) a)))
((eq (caar e) 'lambda)
(eval. (caddar e)
(append. (pair. (cadar e) (evlis. (cdr
a)))))&/blockquote&与此同时,程序员和艺术家们似乎又使用相同的概念,比如美感,比如品位,比如原创:&br&&blockquote&美感是第一道关卡,丑陋的数学在世界上无法生存。——哈代《一个数学家的道歉》&br&&br&最近,我与一个在 MIT 教书的朋友交谈。他的研究领域很热门,每年申请他的研究生的人多得让他应付不过来。“很多人看上去很聪明,”他说,“但是我不知道他们的品味如何”。&br&&br&刚入门的新手不知不觉地模仿他人,逐渐熟练之后才开始创作原创性作品。最后他会意识到,把事情做对比原创性更重要。&/blockquote&&br&上面这几句引文都出自《黑客与画家》第九章,设计者的品位。是不是我们在欺世盗名?作为工程师,程序员们对自己设计的程序结构有近乎狂热的偏执:热衷于不停地增删修改,使得它们能够完成看似简单的循环输出,也会为了重构还是重用争论不休。也许在外人看来这么干很无聊,但回头看看作家们对自己的文章的字斟句酌,和建筑家们在蓝图上的冥思苦想,还有画家们对临摹的耳提面命,我们不难发现,其实这两拨人做的都是同样的事情:我们都在为了自己心目中的完美形象而偏执。&br&&br&=== 价值观?===&br&有人说程序员不懂人情世故,可是也别忘了尼禄也曾经为了心目中的美火烧罗马;有人说程序员不善言辞,可梵高在世时一样以沉默寡言著称。有人说程序员狂妄而傲慢,先生们女士们,请回忆一下我们可敬的奥斯卡·王尔德先生的名言:“The gods had given me almost everything. But I let myself be lured into long spells of senseless and sensual ease. I amused myself with being a FLANEUR, a dandy, a man of fashion. I surrounded myself with the smaller natures and the meaner minds. I became the spendthrift of my own genius, and to waste an eternal youth gave me a curious joy.” 这算恭谨谦和么?所以承认吧,程序员们的价值取向和艺术家们没什么不同。&br&&br&&br&这也不是,那也不是,那么究竟程序员是一群吃了什么药的疯子?好吧,是我们专注的专业的问题。程序的世界是一个基于实证的分析和推理的金字塔,只有相信下面这些信念的人才能最终坚持在程序的道路上走下去:&ol&&li&任何事物都是可以被认识和描述的。——请不要和我说“你不理解我”。&/li&&li&任何行为的背后都有逻辑在支撑。——请不要和我说“我就是突然这么想到的”。&/li&&li&数学是描述客观世界的最佳工具。——请不要和我说“这就是神的造物”。&/li&&li&理论上的完美不能代替实践中的妥协。——请不要和我说“这就是我想的,它就是对的”。&/li&&li&对特定的问题总是存在最优的解法。——请不要和我说“不行了,我做不到了”。&/li&&/ol&&br&如果连信念和偏见的关系和区别都说不清楚,那么在评判一个人时几乎必然产生误解。更别说你在评论一个群体。&br&&br&参考资料:&ul&&li&Paul Graham 的《黑客与画家》。&a href=&///?target=http%3A///subject/1236778/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/subject&/span&&span class=&invisible&&/1236778/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&。豆瓣读书上已经有电子版。&br&&/li&&li&《哥德尔、艾舍尔、巴赫书:集异璧之大成》。&a href=&///?target=http%3A///subject/1291204/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/subject&/span&&span class=&invisible&&/1291204/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/li&&li&《深渊书简》&a href=&///?target=http%3A///wilde/de_profundis.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/wilde/de_pro&/span&&span class=&invisible&&fundis.html&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a& &/li&&/ul&
我不喜欢提问里的说法。 学科教育的狭隘性?知识的结构性缺陷造成问题?那么请问,什么是结构性缺陷?我们都从基础教育过来,基础学科中包含的物理、化学、语文之类的课程,我们一概不少。如果说是后来的专业分家导致的区别,那么哪一个科目都有取舍,我们…
感觉部分答案没有符合题目的要求,&u&“最好是中文语言”&/u&这一条。&br&&img src=&/b3c28b1ffeec02c297dd4feb3f3c36e4_b.jpg& data-rawwidth=&614& data-rawheight=&84& class=&origin_image zh-lightbox-thumb& width=&614& data-original=&/b3c28b1ffeec02c297dd4feb3f3c36e4_r.jpg&&&br&我来班门弄斧一下吧,把我JavaScript学习过程中常去的一些网站分享给大家:&br&
=========================增加=================================&br&&ol&&li&首先增加一个重要的内容:&a href=&///?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/JavaScript& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript | MDN&i class=&icon-external&&&/i&&/a&&br&为什么首先推荐它呢?曾任Mozilla公司首席首席技术官的Brendan Eich是JavaScript主要创造者与架构师。&br&这个是 Mozilla 开发者网络社区的学习资料,比W3school 要好,对于疏通JavaScript很有益处。&img src=&/7efacffda4d2298_b.jpg& data-rawwidth=&1364& data-rawheight=&651& class=&origin_image zh-lightbox-thumb& width=&1364& data-original=&/7efacffda4d2298_r.jpg&&&br&&/li&&li&想了解&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ECMAScript 6 入门&i class=&icon-external&&&/i&&/a&的, 阮老师的这个网站不要错过。&br&&img src=&/815dd3b9f871b56b264d85b004c99e9b_b.jpg& data-rawwidth=&1365& data-rawheight=&645& class=&origin_image zh-lightbox-thumb& width=&1365& data-original=&/815dd3b9f871b56b264d85b004c99e9b_r.jpg&&&br&&/li&&li&居然忘记InfoQ这个网站 ,&a href=&///?target=https%3A///link%3Furl%3DNt9FFBWe0j1o_pqIqrgaxI13N_yRILyvI-vXDwExyrbH58E7BFN5wudRtMoDVW2T%26wd%3Dinfoq%25E4%25B8%25AD%25E6%E7%25AB%2599%26issp%3D1%26f%3D3%26ie%3Dutf-8%26tn%3Dbaiduhome_pg%26oq%3Dinfoq%26rsp%3D0%26inputT%3D3019& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&InfoQ - 促进软件开发领域知识与创新的传播&i class=&icon-external&&&/i&&/a&,这是他的&a href=&///?target=http%3A//q.com/cn/javascript/%3Futm_source%3Dinfoq%26utm_medium%3Dheader_graybar%26utm_campaign%3Dtopic_clk& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript&i class=&icon-external&&&/i&&/a&频道。&br&InfoQ是一家国际技术媒体,虽然网站不是很漂亮,但是内容大于样式。&br&网站的JavaScript频道知识很多,很多国际上的新知识。有&a href=&///?target=http%3A//q.com/cn/javascript/news/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript &
第1页&i class=&icon-external&&&/i&&/a& || &a href=&///?target=http%3A//q.com/cn/javascript/articles/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript &
第1页&i class=&icon-external&&&/i&&/a& || &a href=&///?target=http%3A//q.com/cn/javascript/minibooks/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript &
第1页&i class=&icon-external&&&/i&&/a& ||
&a href=&///?target=http%3A//q.com/cn/javascript/presentations/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript &
第1页&i class=&icon-external&&&/i&&/a& ||&a href=&///?target=http%3A//q.com/cn/javascript/interviews/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript &
第1页&i class=&icon-external&&&/i&&/a& ,详细点链接。&br&&br&=============================================================&/li&&li&&a href=&///?target=http%3A//div.io/node/javascript& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Div.IO&i class=&icon-external&&&/i&&/a&: &br&最近发现了一个高质量的前端社区,聚集了很多各大公司前端牛人,里面的干货很多,不过这个网站需要注册码才可以注册,但是假如仅仅是阅读上面的文章,不需要注册码也是可以的。见图:页面很简洁,还有阅读效果很好。&br&&img src=&/9c6ae7ce482a99b108dfdd4_b.jpg& data-rawwidth=&1366& data-rawheight=&651& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/9c6ae7ce482a99b108dfdd4_r.jpg&&&br&&/li&&li&&a href=&///?target=http%3A//www./& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&前端乱炖, 最专业的前端技术内容社区&i class=&icon-external&&&/i&&/a&&br&这个网站是我去得很多的一个网站,里面有一个专栏模块,用于展示各种原创文章,原创翻译文章,知识性比较强,内容比较专业和系统。&br&这个网站的特点是更新较多,同时大大也很多。&br&&img src=&/7ba70c2fb3b62e070e97c_b.jpg& data-rawwidth=&1360& data-rawheight=&575& class=&origin_image zh-lightbox-thumb& width=&1360& data-original=&/7ba70c2fb3b62e070e97c_r.jpg&&&br&&/li&&li&&a href=&///?target=https%3A//cnodejs.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CNode:Node.js专业中文社区&i class=&icon-external&&&/i&&/a&&br&想学习Nodejs吗?那么这个网站很建议你去,而且里面的人很友善,或者说彼此交流学习的氛围超级好,这个社区是由 &a data-hash=&7cd6a45d341fb2b4b35b& href=&///people/7cd6a45d341fb2b4b35b& class=&member_mention& data-editable=&true& data-title=&@朴灵& data-hovercard=&p$b$7cd6a45d341fb2b4b35b&&@朴灵&/a&他们创办的。&br&网站精华栏目见截图:&br&&img src=&/a69dfbeef39b4b_b.jpg& data-rawwidth=&1366& data-rawheight=&652& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/a69dfbeef39b4b_r.jpg&&&br&&/li&&li&&a href=&///?target=http%3A///articles/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&技术文章 FEX 做最专业的前端&i class=&icon-external&&&/i&&/a&&br&百度FEX一直很牛逼,FEX 是百度「Web 前端研发部」的内部名称,其中 FE 是 Front End 的缩写,X 代表他们不仅关注前端技术,还更重视全端及全栈的能力。开源项目很多。很多思想值得我们学习。&br&&img src=&/e7a75cf4e1d6afcace1e720_b.jpg& data-rawwidth=&1363& data-rawheight=&671& class=&origin_image zh-lightbox-thumb& width=&1363& data-original=&/e7a75cf4e1d6afcace1e720_r.jpg&&&br&&/li&&li&&a href=&///?target=http%3A///tag/javascript/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript on Smashing Magazine&i class=&icon-external&&&/i&&/a&&br&接着来一个国外的,里面新东西很多,不过全部是英文的,有点考验你的英语阅读能力。(这个不符合题目要求,但还是推荐一下)&br&&img src=&/1c906c8e95aa4d7d5cc66db9fa186fc8_b.jpg& data-rawwidth=&1366& data-rawheight=&649& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/1c906c8e95aa4d7d5cc66db9fa186fc8_r.jpg&&&br&&/li&&li&&a href=&///?target=https%3A///xufei/blog/issues& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Issues · xufei/blog · GitHub&i class=&icon-external&&&/i&&/a&&br&&a data-hash=&cc0145aee04dd53cc6590edd& href=&///people/cc0145aee04dd53cc6590edd& class=&member_mention& data-editable=&true& data-title=&@徐飞& data-hovercard=&p$b$cc0145aee04dd53cc6590edd&&@徐飞&/a& 是我所知,国内研究angular很透彻的一个人,github 博客上面关于angular的精华分享很多,文章讲的很透彻,每一次他出文章,一般都会认真读一遍,很受益的&br&&img src=&/2b3f443eed9daadccedf9c8f_b.jpg& data-rawwidth=&1355& data-rawheight=&652& class=&origin_image zh-lightbox-thumb& width=&1355& data-original=&/2b3f443eed9daadccedf9c8f_r.jpg&&&br&&/li&&li&&a href=&///?target=http%3A///sharpxiajun/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&夏天的森林 - 博客园&i class=&icon-external&&&/i&&/a&&br&夏天的森林,博客形式主要以“连载”为主,不得不说,你的花一些时间去学习,看过之后能够对于JavaScript的某一些方面有很深的理解:&br&&img src=&/474d8e28ef74cc_b.jpg& data-rawwidth=&1365& data-rawheight=&650& class=&origin_image zh-lightbox-thumb& width=&1365& data-original=&/474d8e28ef74cc_r.jpg&&&br&&/li&&li&&a href=&///?target=http%3A///TomXu/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&汤姆大叔 - 博客园&i class=&icon-external&&&/i&&/a&&br&应该很多搞前端的人都看过汤姆大叔的书,他的博客园里面东西很多很多,值得常去看看。&img src=&/6bbfae5a8525ae02effc6ef3a21c07ef_b.jpg& data-rawwidth=&1366& data-rawheight=&654& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/6bbfae5a8525ae02effc6ef3a21c07ef_r.jpg&&&/li&&li&&a href=&///?target=https%3A//bonsaiden.github.io/JavaScript-Garden/zh/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript 秘密花园&i class=&icon-external&&&/i&&/a&&br&超级推荐这个,&strong&JavaScript秘密花园&/strong&是一个不断更新的文档,主要关心JavaScript一些古怪用法。 对于如何避免常见的错误,难以发现的问题,以及性能问题和不好的实践给出建议, 初学者可以籍此深入了解JavaScript的语言特性。&br&&img src=&/1b1897fdaac5d3f8b4654_b.jpg& data-rawwidth=&1355& data-rawheight=&653& class=&origin_image zh-lightbox-thumb& width=&1355& data-original=&/1b1897fdaac5d3f8b4654_r.jpg&&&br&&/li&&li&&b&&a href=&///?target=http%3A///r/gAMm9Q& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/r/gAMm9Q&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&/b&我又来推荐这个代码的打怪升级网站,主要你可以用它来练习你的JavaScript,对于提高你的JavaScript编程能力是很重要的。同时对于你英语能力的提高是很重要的。&br&&img src=&/21891fcc19bf251c0bcd5b81_b.jpg& data-rawwidth=&1366& data-rawheight=&648& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/21891fcc19bf251c0bcd5b81_r.jpg&&&br&&/li&&li&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&前端网址导航&i class=&icon-external&&&/i&&/a&&br&当你看到这里来了,证明这个才是好东西,简历ctrl+d,前端导航网站,分类不错,小东西很多。&br&&img src=&/3deb4f276baefa8ccfe94_b.jpg& data-rawwidth=&1366& data-rawheight=&650& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/3deb4f276baefa8ccfe94_r.jpg&&&br&&/li&&li&其实对于JavaScript的学习,我觉得最重要的还是多练习,多看书,多做小项目,那些前端博客或者网站一般是给你带来一种思维,或者说对于前端的思考方式,假如看了以后不去练习,其实可能作用不是很大。&br&&br&&/li&&li&=========================偏题补充=============================&br&系统学习JavaScript,可能看书效果好一点,推荐好书,★代表深浅度:&br&&/li&&/ol&&ul&&li&&a href=&///?target=http%3A///subject/6038371/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript DOM编程艺术 (第2版)&i class=&icon-external&&&/i&&/a&★&/li&&li&&a href=&///?target=http%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript高级程序设计(第3版)&i class=&icon-external&&&/i&&/a&★★&/li&&li&&a href=&///?target=http%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&锋利的jQuery&i class=&icon-external&&&/i&&/a&★★&/li&&li&&a href=&///?target=http%3A///subject/5362856/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&高性能JavaScript&i class=&icon-external&&&/i&&/a&★★★&/li&&li&&a href=&///?target=http%3A///subject/3590768/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript语言精粹&i class=&icon-external&&&/i&&/a&★★★&/li&&li&&a href=&///?target=http%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript权威指南&i class=&icon-external&&&/i&&/a&★★★&/li&&li&&a href=&///?target=http%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&编写可维护的JavaScript&i class=&icon-external&&&/i&&/a&★★★&/li&&li&&a href=&///?target=http%3A///subject/3012828/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JAVASCRIPT语言精髓与编程实践&i class=&icon-external&&&/i&&/a&★★★&/li&&li&&a href=&///?target=http%3A///Effective-JavaScript-Specific-Software-Development/dp/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Effective Javascript&i class=&icon-external&&&/i&&/a&★★★&/li&&li&&a href=&///?target=http%3A///subject/3176860/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Secrets of the JavaScript Ninja&i class=&icon-external&&&/i&&/a&★★★&/li&&li&&a href=&///?target=http%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript模式&i class=&icon-external&&&/i&&/a&★★★&/li&&li&&a href=&///?target=http%3A///subject/3329540/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript设计模式&i class=&icon-external&&&/i&&/a&★★★★&/li&&li&&a href=&///?target=http%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&基于MVC的JavaScript Web富应用开发&i class=&icon-external&&&/i&&/a&★★★&br&&br&&/li&&/ul&//&b&每次买了新书都特别兴奋,所以说多买书吧&/b&。&br&每个想提高JavaScript能力的人都应该有一本《JavaScript权威指南》。这是一本字典式的读物,虽然不适合初学者,但是可以把它当作你的第二本JavaScript书籍。&br&&img src=&/471c7f6ff5cefd01fda56e5_b.jpg& data-rawwidth=&960& data-rawheight=&1280& class=&origin_image zh-lightbox-thumb& width=&960& data-original=&/471c7f6ff5cefd01fda56e5_r.jpg&&&img src=&/02da5c7bc23b9acec32c_b.jpg& data-rawwidth=&820& data-rawheight=&616& class=&origin_image zh-lightbox-thumb& width=&820& data-original=&/02da5c7bc23b9acec32c_r.jpg&&&br&//大家看到这本书是不是很兴奋?
感觉部分答案没有符合题目的要求,“最好是中文语言”这一条。 我来班门弄斧一下吧,把我JavaScript学习过程中常去的一些网站分享给大家: =========================增加================================= 首先增加一个重要的内容: 为什…
我做过两个……&br&&b&第一个,Inziu(神秀):&/b&&b&&a href=&///?target=http%3A//be5invis.github.io/Iosevka/inziu.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Inziu Iosevka Downloads&i class=&icon-external&&&/i&&/a&&/b&,基于 Iosevka,自带中文,清晰如刀哥&br&&b&第二个:&/b&&a href=&///?target=http%3A///s/1eQs8RS2& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Descret-0629&i class=&icon-external&&&/i&&/a&,基于 CMU,可配合前面那个使用&br&&img src=&/7ec9a535a8aff6_b.jpg& data-rawwidth=&1427& data-rawheight=&1536& class=&origin_image zh-lightbox-thumb& width=&1427& data-original=&/7ec9a535a8aff6_r.jpg&&主要特点是严格半角,不用担心汉字扭曲或者错位。&br&————————————————————————————————————————————&br&&a data-hash=&2ae8b3af01d40abc77ebeda7ecc350a9& href=&///people/2ae8b3af01d40abc77ebeda7ecc350a9& class=&member_mention& data-editable=&true& data-title=&阿玲姐姐& data-hovercard=&p$b$2ae8b3af01d40abc77ebeda7ecc350a9&&阿玲姐姐&/a&说「成功的开源软件都要有捐赠地址,还要放在最显眼的地方」&br&&b&项目地址:&a href=&///?target=https%3A///be5invis/sfdhanautohint& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&be5invis/sfdhanautohint &i class=&icon-external&&&/i&&/a&· &a href=&///?target=https%3A///be5invis/Iosevka& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&be5invis/Iosevka&i class=&icon-external&&&/i&&/a&&/b&&br&&b&捐赠地址:支付宝 &/b&&br&&b&支持原创?一元也可?有你支持?有我更新&/b&
我做过两个…… 第一个,Inziu(神秀):,基于 Iosevka,自带中文,清晰如刀哥 第二个:,基于 CMU,可配合前面那个使用 主要特点是严格半角,不用担心汉字扭曲或者错位。 —————————————————————…
我来说两句吧:目前几乎没有纯粹的 C/C++开发游戏服务端的。&br&&br&早年开发游戏必须用C++,这没得说,年,java还没有nio,其他动态语言不抗重负,只能C/C++能开发出完整可用的游戏服务端。直到2005年,韩国的游戏很多都还是纯C++写服务端,金山之前也开发过很多纯粹C++的游戏服务端,后来大家都切了。&br&&br&现代选择有很多:java + javascript, c+python, c+lua, scala, go, erlang。我们面向性能的服务器用 java,面向逻辑服务器 python,面向高并发的会选择 scala,次一级高并发或者性能测试程序(机器人)会选择 gevent。那是不是我们就不用C++呢?我们用 C来做网络,不用C++,但是C的比例在所有代码中占比有限。&br&&br&这是否意味我们可以放弃C/C++了?也不是:C语言是一把锋利的匕首,而现代动态语言是一把长剑。平时匕首可以藏在身上,大部分时候用长剑披荆斩棘就够了,但当你碰到坚硬的石头,长剑不管用了,那么拿出匕首来果断的切碎他。&br&&br&对于一个成熟领域而言,我的建议是尽量用更高级一点的开发语言,因为游戏开发很多核心技术都有了较为妥当的解决方法。大量的服务端逻辑其实都是在等待,等待网络,等待数据库,这种情况下用C得不偿失。但是服务端有一些地方还是躲不开C/C++,比如当服务器涉及到 3D计算的话(国内很多2D服务端,国外很多3D服务端),大量的矢量矩阵,除了用C++封装出一套好用的数学库外,即便直接用java写,那也是很麻烦的。再比如现在快速动作越来越多,为了让玩家操作更流畅,我需要基于 UDP快速可靠协议,协议开发用 java或者scala,性能上是没办法满足要求的,况且协议实现后要和客户端通信,你没法让所有客户端跟着你一起用java/scala。再比如某些cpu密集的抽象度高的模块,如 aoi或者 ai模块。&br&&br&对于一个新兴领域而言,C/C++很多情况下是你别无选择的东西。比如移动化浪潮刚起步的时候,还没有啥 cocos或者 unity你真要开发游戏,你必须迅速的使用起 OpenGL ES和 OpenSL,然后再叠加某一脚本,以快制胜,第一批移动浪潮上发财的就是这些游戏。又或者,你可以根本躲开,先不介入,等到几年后cocos和 unity成熟了,你在介入用lua / C#写程序。再比如服务端你如果离开熟悉的游戏和web,去开发一个陌生的领域,如流媒体服务,你会发现这怎么和10年前的游戏一样呀,什么高级工具都不给我用用,这时你可以再等个四五年应该高级工具会出现,异或你想领先别人时,你就果断的拿出 C/C++来解决之,这就是C独有的开拓新领域能力。&br&&br&大部分答案都是非黑即白,非此即彼。不要只会C不会动态语言,避免成为一个傻逼;也不要只会动态语言不会C,避免离开熟悉的温室就活不下去。对于一个新手而言,如果什么都没学过,我的建议是先用快速开发的东西,把项目弄起来再说,有精力有机会的情况下,也不能完全放弃一些基础的东西,让自己残缺了。&br&&br&PS:在相同架构下,就纯粹性能而言,各种语言性能差距到底是多少呢?如果只开发回合制这些慢节奏游戏,或者HTTP接口,大部分情况都在等待数据库等待用户消息的话,差别确实不大,的确可能5%都不到。如果cpu密集了,那么可以参考下面的图表,总体来说是10-50倍的性能差别:&br&&img src=&/36ce0e9ad05a38e9c12cf52e24179ae6_b.jpg& data-rawwidth=&289& data-rawheight=&339& class=&content_image& width=&289&&&br&有人问,说了半天,这个也不行,那个也不完美,而我时间有限,有没有一个更经济实惠的方法呀?如何才一次性达到彼岸呀?时间有限项目吃紧有没有更好的选择?我说有啊!那就是 java。&br&&br&国内游戏开发绕来绕去还是脚本+C+erlang+go,难道大家就不会其他东西了么?大部分可以的情况下,除了非用C/C++,我推荐各位认真考虑下 java,这个性能上最接近C的东西,能承当大部分cpu密集型事务,却又不会象c那样 crash了找都找不到问题在哪里。同时面向高并发时基于原生jvm的 scala可以提供类似 erlang的简单方式,函数式编程 & 大规模并发协程 & actor;同时 java可以很方便的同 javascript结合,js的速度应该是动态语言里面最快的吧。再者 java还有 groovy,可以提供 python/ruby的泛型编程,用超高的开发效率和 python/ruby媲美,同时还能和 scala 结合实现高并发。最重要的是写 java好招聘,到处都是写 java的工程师,大部分语言级的培训都可以省略了。&br&&br&国内游戏开发者很多拒绝学习 java,因为很多开发者自己是碰都没碰过。现在拒绝 java的人,大部分只是在游戏圈子里面打转的人,偶尔开发下 web,缺乏其他行业和领域的经验。看看除游戏外,当今多少世界级的开源服务器是用 java开发的?游戏就真有那么特殊么?我看不是,国外大把java开发的游戏服务端,各位如果知道游戏服务端领域有啥 java技术栈解决不了的事情,麻烦告诉我一声。再看看java上下游的 scala, javascript, groovy这些东西。所以建议各位,有空有条件的情况下,认真考虑下 java技术栈,世界很大,不是只有游戏;即便游戏,现在的开发方法真的对吗?&br&&br&---------------------------------------------&br&PS,刚才又了解了一下,原来国内最近这两年用 java开发游戏服务器是越来越普遍了,比我之前想的还多,这是好事情呀。
我来说两句吧:目前几乎没有纯粹的 C/C++开发游戏服务端的。 早年开发游戏必须用C++,这没得说,年,java还没有nio,其他动态语言不抗重负,只能C/C++能开发出完整可用的游戏服务端。直到2005年,韩国的游戏很多都还是纯C++写服务端,金山之前也开…
&b&Hadoop&/b&&br&首先看一下Hadoop解决了什么问题,Hadoop就是解决了大数据(大到一台计算机无法进行存储,一台计算机无法在要求的时间内进行处理)的可靠存储和处理。&br&&ul&&li&HDFS,在由普通PC组成的集群上提供高可靠的文件存储,通过将块保存多个副本的办法解决服务器或硬盘坏掉的问题。&/li&&li&MapReduce,通过简单的Mapper和Reducer的抽象提供一个编程模型,可以在一个由几十台上百台的PC组成的不可靠集群上并发地,分布式地处理大量的数据集,而把并发、分布式(如机器间通信)和故障恢复等计算细节隐藏起来。而Mapper和Reducer的抽象,又是各种各样的复杂数据处理都可以分解为的基本元素。这样,复杂的数据处理可以分解为由多个Job(包含一个Mapper和一个Reducer)组成的有向无环图(DAG),然后每个Mapper和Reducer放到Hadoop集群上执行,就可以得出结果。&/li&&/ul&&img src=&/adb253dbce2cbc_b.jpg& data-rawwidth=&627& data-rawheight=&195& class=&origin_image zh-lightbox-thumb& width=&627& data-original=&/adb253dbce2cbc_r.jpg&&(图片来源:&a href=&///?target=http%3A//www.slideshare.net/davidengfer/intro-to-the-hadoop-stack-javamug& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&slideshare.net/davideng&/span&&span class=&invisible&&fer/intro-to-the-hadoop-stack-javamug&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&)&br&&br&用MapReduce统计一个文本文件中单词出现的频率的示例WordCount请参见:&a href=&///?target=http%3A//wiki.apache.org/hadoop/WordCount& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&WordCount - Hadoop Wiki&i class=&icon-external&&&/i&&/a&,如果对MapReduce不恨熟悉,通过该示例对MapReduce进行一些了解对理解下文有帮助。&br&&br&在MapReduce中,Shuffle是一个非常重要的过程,正是有了看不见的Shuffle过程,才可以使在MapReduce之上写数据处理的开发者完全感知不到分布式和并发的存在。&br&&img src=&/57b942a32d5b035a7f1d_b.jpg& data-rawwidth=&774& data-rawheight=&367& class=&origin_image zh-lightbox-thumb& width=&774& data-original=&/57b942a32d5b035a7f1d_r.jpg&&(图片来源: Hadoop Definitive Guide By Tom White)&br&广义的Shuffle是指图中在Map和Reuce之间的一系列过程。&br&&br&&b&Hadoop的局限和不足&/b&&br&但是,MapRecue存在以下局限,使用起来比较困难。&br&&ul&&li&抽象层次低,需要手工编写代码来完成,使用上难以上手。&/li&&li&只提供两个操作,Map和Reduce,表达力欠缺。&/li&&li&一个Job只有Map和Reduce两个阶段(Phase),复杂的计算需要大量的Job完成,Job之间的依赖关系是由开发者自己管理的。&/li&&li&处理逻辑隐藏在代码细节中,没有整体逻辑&/li&&li&中间结果也放在HDFS文件系统中&/li&&li&ReduceTask需要等待所有MapTask都完成后才可以开始&/li&&li&时延高,只适用Batch数据处理,对于交互式数据处理,实时数据处理的支持不够&/li&&li&对于迭代式数据处理性能比较差&/li&&/ul&&br&比如说,用MapReduce实现两个表的Join都是一个很有技巧性的过程,如下图所示:&br&&img src=&/886cdc16b356e016d3ce_b.jpg& data-rawwidth=&713& data-rawheight=&359& class=&origin_image zh-lightbox-thumb& width=&713& data-original=&/886cdc16b356e016d3ce_r.jpg&&(图片来源:&a href=&///?target=http%3A////real-world-hadoop-implementing-a-left-outer-join-in-hadoop-map-reduce.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Real World Hadoop&i class=&icon-external&&&/i&&/a&)&br&&br&因此,在Hadoop推出之后,出现了很多相关的技术对其中的局限进行改进,如Pig,Cascading,JAQL,OOzie,Tez,Spark等。&br&&br&&b&Apache Pig&/b&&br&Apache Pig也是Hadoop框架中的一部分,Pig提供类SQL语言(Pig Latin)通过MapReduce来处理大规模半结构化数据。而Pig Latin是更高级的过程语言,通过将MapReduce中的设计模式抽象为操作,如Filter,GroupBy,Join,OrderBy,由这些操作组成&b&有向无环图(DAG)&/b&。例如如下程序:&br&&div class=&highlight&&&pre&&code class=&language-bash&&&span class=&nv&&visits&/span&
&span class=&o&&=&/span& load ‘/data/visits’ as &span class=&o&&(&/span&user, url, &span class=&nb&&time&/span&&span class=&o&&)&/span&&span class=&p&&;&/span&
&span class=&nv&&gVisits&/span&
&span class=&o&&=&/span& group visits by url&span class=&p&&;&/span&
&span class=&nv&&visitCounts&/span&
&span class=&o&&=&/span& foreach gVisits generate url, count&span class=&o&&(&/span&visits&span class=&o&&)&/span&&span class=&p&&;&/span&
&span class=&nv&&urlInfo&/span&
&span class=&o&&=&/span& load ‘/data/urlInfo’ as &span class=&o&&(&/span&url, category, pRank&span class=&o&&)&/span&&span class=&p&&;&/span&
&span class=&nv&&visitCounts&/span&
&span class=&o&&=&/span& join visitCounts by url, urlInfo by url&span class=&p&&;&/span&
&span class=&nv&&gCategories&/span& &span class=&o&&=&/span& group visitCounts by category&span class=&p&&;&/span&
&span class=&nv&&topUrls&/span& &span class=&o&&=&/span& foreach gCategories generate top&span class=&o&&(&/span&visitCounts,10&span class=&o&&)&/span&&span class=&p&&;&/span&
store topUrls into ‘/data/topUrls’&span class=&p&&;&/span&
&/code&&/pre&&/div&描述了数据处理的整个过程。&br&&br&而Pig Latin又是通过编译为MapReduce,在Hadoop集群上执行的。上述程序被编译成MapReduce时,会产生如下图所示的Map和Reduce:&br&&img src=&/27f938d43e54be4eba91c7899daa3bca_b.jpg& data-rawwidth=&692& data-rawheight=&455& class=&origin_image zh-lightbox-thumb& width=&692& data-original=&/27f938d43e54be4eba91c7899daa3bca_r.jpg&&&br&(图片来源:&a href=&///?target=http%3A//cs.nyu.edu/courses/Fall12/CSCI-GA./sigmod08-pig-latin.ppt& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&cs.nyu.edu/courses/Fall&/span&&span class=&invisible&&12/CSCI-GA./sigmod08-pig-latin.ppt&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&)&br&&br&Apache Pig解决了MapReduce存在的大量手写代码,语义隐藏,提供操作种类少的问题。类似的项目还有Cascading,JAQL等。&br&&br&&b&Apache Tez&/b&&br&Apache Tez,Tez是HortonWorks的Stinger Initiative的的一部分。作为执行引擎,Tez也提供了&b&有向无环图(DAG)&/b&,DAG由顶点(Vertex)和边(Edge)组成,Edge是对数据的移动的抽象,提供了One-To-One,BroadCast,和Scatter-Gather三种类型,只有Scatter-Gather才需要进行Shuffle。&br&&br&以如下SQL为例:&br&&div class=&highlight&&&pre&&code class=&language-sql&&&span class=&k&&SELECT&/span& &span class=&n&&a&/span&&span class=&p&&.&/span&&span class=&k&&state&/span&&span class=&p&&,&/span& &span class=&k&&COUNT&/span&&span class=&p&&(&/span&&span class=&o&&*&/span&&span class=&p&&),&/span&
&span class=&n&&AVERAGE&/span&&span class=&p&&(&/span&&span class=&k&&c&/span&&span class=&p&&.&/span&&span class=&n&&price&/span&&span class=&p&&)&/span&
&span class=&k&&FROM&/span& &span class=&n&&a&/span&
&span class=&k&&JOIN&/span& &span class=&n&&b&/span& &span class=&k&&ON&/span& &span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&.&/span&&span class=&n&&id&/span& &span class=&o&&=&/span& &span class=&n&&b&/span&&span class=&p&&.&/span&&span class=&n&&id&/span&&span class=&p&&)&/span&
&span class=&k&&JOIN&/span& &span class=&k&&c&/span& &span class=&k&&ON&/span& &span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&.&/span&&span class=&n&&itemId&/span& &span class=&o&&=&/span& &span class=&k&&c&/span&&span class=&p&&.&/span&&span class=&n&&itemId&/span&&span class=&p&&)&/span&
&span class=&k&&GROUP&/span& &span class=&k&&BY&/span& &span class=&n&&a&/span&&span class=&p&&.&/span&&span class=&k&&state&/span&
&/code&&/pre&&/div&&img src=&/666f395a113ccc523a32_b.jpg& data-rawwidth=&864& data-rawheight=&431& class=&origin_image zh-lightbox-thumb& width=&864& data-original=&/666f395a113ccc523a32_r.jpg&&(图片来源:&a href=&///?target=http%3A//www.slideshare.net/hortonworks/apache-tez-accelerating-hadoop-query-processing& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&slideshare.net/hortonwo&/span&&span class=&invisible&&rks/apache-tez-accelerating-hadoop-query-processing&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&)&br&途中蓝色方块表示Map,绿色方块表示Reduce,云状表示写屏障(write barrier,一种内核机制,可以理解为持久的写),Tez的优化主要体现在:&br&&ol&&li&去除了连续两个作业之间的写屏障&/li&&li&去除了每个工作流中多余的Map阶段(Stage)&/li&&/ol&通过提供DAG语义和操作,提供了整体的逻辑,通过减少不必要的操作,Tez提升了数据处理的执行性能。&br&&br&&b&Apache Spark&/b&&br&Apache Spark是一个新兴的大数据处理的引擎,主要特点是提供了一个集群的分布式内存抽象,以支持需要工作集的应用。&br&&br&这个抽象就是RDD(Resilient Distributed Dataset),RDD就是一个不可变的带分区的记录集合,RDD也是Spark中的编程模型。Spark提供了RDD上的两类操作,转换和动作。转换是用来定义一个新的RDD,包括map, flatMap, filter, union, sample, join, groupByKey, cogroup, ReduceByKey, cros, sortByKey, mapValues等,动作是返回一个结果,包括collect, reduce, count, save, lookupKey。&br&&br&Spark的API非常简单易用,Spark的WordCount的示例如下所示:&br&&div class=&highlight&&&pre&&code class=&language-scala&&&span class=&k&&val&/span& &span class=&n&&spark&/span& &span class=&k&&=&/span& &span class=&k&&new&/span& &span class=&nc&&SparkContext&/span&&span class=&o&&(&/span&&span class=&n&&master&/span&&span class=&o&&,&/span& &span class=&n&&appName&/span&&span class=&o&&,&/span& &span class=&o&&[&/span&&span class=&kt&&sparkHome&/span&&span class=&o&&],&/span& &span class=&o&&[&/span&&span class=&kt&&jars&/span&&span class=&o&&])&/span&
&span class=&k&&val&/span& &span class=&n&&file&/span& &span class=&k&&=&/span& &span class=&n&&spark&/span&&span class=&o&&.&/span&&span class=&n&&textFile&/span&&span class=&o&&(&/span&&span class=&s&&&hdfs://...&&/span&&span class=&o&&)&/span&
&span class=&k&&val&/span& &span class=&n&&counts&/span& &span class=&k&&=&/span& &span class=&n&&file&/span&&span class=&o&&.&/span&&span class=&n&&flatMap&/span&&span class=&o&&(&/span&&span class=&n&&line&/span& &span class=&k&&=&&/span& &span class=&n&&line&/span&&span class=&o&&.&/span&&span class=&n&&split&/span&&span class=&o&&(&/span&&span class=&s&&& &&/span&&span class=&o&&))&/span&
&span class=&o&&.&/span&&span class=&n&&map&/span&&span class=&o&&(&/span&&span class=&n&&word&/span& &span class=&k&&=&&/span& &span class=&o&&(&/span&&span class=&n&&word&/span&&span class=&o&&,&/span& &span class=&mi&&1&/span&&span class=&o&&))&/span&
&span class=&o&&.&/span&&span class=&n&&reduceByKey&/span&&span class=&o&&(&/span&&span class=&k&&_&/span& &span class=&o&&+&/span& &span class=&k&&_&/span&&span class=&o&&)&/span&
&span class=&n&&counts&/span&&span class=&o&&.&/span&&span class=&n&&saveAsTextFile&/span&&span class=&o&&(&/span&&span class=&s&&&hdfs://...&&/span&&span class=&o&&)&/span&
&/code&&/pre&&/div&其中的file是根据HDFS上的文件创建的RDD,后面的flatMap,map,reduceByKe都创建出一个新的RDD,一个简短的程序就能够执行很多个转换和动作。&br&&br&在Spark中,所有RDD的转换都是是&b&惰性求值&/b&的。RDD的转换操作会生成新的RDD,新的RDD的数据依赖于原来的RDD的数据,每个RDD又包含多个分区。那么一段程序实际上就构造了一个由相互依赖的多个RDD组成的&b&有向无环图(DAG)。&/b&并通过在RDD上执行动作将这个有向无环图作为一个Job提交给Spark执行。&br&&br&例如,上面的WordCount程序就会生成如下的DAG&br&&div class=&highlight&&&pre&&code class=&language-scala&&&span class=&n&&scala&/span&&span class=&o&&&&/span& &span class=&n&&counts&/span&&span class=&o&&.&/span&&span class=&n&&toDebugString&/span&
&span class=&n&&res0&/span&&span class=&k&&:&/span& &span class=&kt&&String&/span& &span class=&o&&=&/span&
&span class=&nc&&MapPartitionsRDD&/span&&span class=&o&&[&/span&&span class=&err&&7&/span&&span class=&o&&]&/span& &span class=&n&&at&/span& &span class=&n&&reduceByKey&/span& &span class=&n&&at&/span& &span class=&o&&&&/span&&span class=&n&&console&/span&&span class=&k&&&:&/span&&span class=&mi&&14&/span& &span class=&o&&(&/span&&span class=&mi&&1&/span& &span class=&n&&partitions&/span&&span class=&o&&)&/span&
&span class=&nc&&ShuffledRDD&/span&&span class=&o&&[&/span&&span class=&err&&6&/span&&span class=&o&&]&/span& &span class=&n&&at&/span& &span class=&n&&reduceByKey&/span& &span class=&n&&at&/span& &span class=&o&&&&/span&&span class=&n&&console&/span&&span class=&k&&&:&/span&&span class=&mi&&14&/span& &span class=&o&&(&/span&&span class=&mi&&1&/span& &span class=&n&&partitions&/span&&span class=&o&&)&/span&
&span class=&nc&&MapPartitionsRDD&/span&&span class=&o&&[&/span&&span class=&err&&5&/span&&span class=&o&&]&/span& &span class=&n&&at&/span& &span class=&n&&reduceByKey&/span& &span class=&n&&at&/span& &span class=&o&&&&/span&&span class=&n&&console&/span&&span class=&k&&&:&/span&&span class=&mi&&14&/span& &span class=&o&&(&/span&&span class=&mi&&1&/span& &span class=&n&&partitions&/span&&span class=&o&&)&/span&
&span class=&nc&&MappedRDD&/span&&span class=&o&&[&/span&&span class=&err&&4&/span&&span class=&o&&]&/span& &span class=&n&&at&/span& &span class=&n&&map&/span& &span class=&n&&at&/span& &span class=&o&&&&/span&&span class=&n&&console&/span&&span class=&k&&&:&/span&&span class=&mi&&14&/span& &span class=&o&&(&/span&&span class=&mi&&1&/span& &span class=&n&&partitions&/span&&span class=&o&&)&/span&
&span class=&nc&&FlatMappedRDD&/span&&span class=&o&&[&/span&&span class=&err&&3&/span&&span class=&o&&]&/span& &span class=&n&&at&/span& &span class=&n&&flatMap&/span& &span class=&n&&at&/span& &span class=&o&&&&/span&&span class=&n&&console&/span&&span class=&k&&&:&/span&&span class=&mi&&14&/span& &span class=&o&&(&/span&&span class=&mi&&1&/span& &span class=&n&&partitions&/span&&span class=&o&&)&/span&
&span class=&nc&&MappedRDD&/span&&span class=&o&&[&/span&&span class=&err&&1&/span&&span class=&o&&]&/span& &span class=&n&&at&/span& &span class=&n&&textFile&/span& &span class=&n&&at&/span& &span class=&o&&&&/span&&span class=&n&&console&/span&&span class=&k&&&:&/span&&span class=&mi&&12&/span& &span class=&o&&(&/span&&span class=&mi&&1&/span& &span class=&n&&partitions&/span&&span class=&o&&)&/span&
&span class=&nc&&HadoopRDD&/span&&span class=&o&&[&/span&&span class=&err&&0&/span&&span class=&o&&]&/span& &span class=&n&&at&/span& &span class=&n&&textFile&/span& &span class=&n&&at&/span& &span class=&o&&&&/span&&span class=&n&&console&/span&&span class=&k&&&:&/span&&span class=&mi&&12&/span& &span class=&o&&(&/span&&span class=&mi&&1&/span& &span class=&n&&partitions&/span&&span class=&o&&)&/span&
&/code&&/pre&&/div&&br&&br&Spark对于有向无环图Job进行调度,确定&b&阶段(Stage)&/b&,&b&分区(Partition)&/b&,&b&流水线(Pipeline)&/b&,&b&任务(Task)&/b&和&b&缓存(Cache)&/b&,进行优化,并在Spark集群上运行Job。RDD之间的依赖分为&b&宽依赖&/b&(依赖多个分区)和&b&窄依赖&/b&(只依赖一个分区),在确定阶段时,需要根据宽依赖划分阶段。根据分区划分任务。&br&&br&&img src=&/d9a22d31fe35d66f8d02_b.jpg& data-rawwidth=&602& data-rawheight=&439& class=&origin_image zh-lightbox-thumb& width=&602& data-original=&/d9a22d31fe35d66f8d02_r.jpg&&(图片来源:&a href=&///?target=https%3A//databricks-training./slides/advanced-spark-training.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&databricks-training.&/span&&span class=&invisible&&/slides/advanced-spark-training.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&)&br&&br&Spark支持故障恢复的方式也不同,提供两种方式,&b&Linage&/b&,通过数据的血缘关系,再执行一遍前面的处理,&b&Checkpoint&/b&,将数据集存储到持久存储中。&br&&br&Spark为&b&迭代式数据处理&/b&提供更好的支持。每次迭代的数据可以保存在内存中,而不是写入文件。&br&&br&Spark的性能相比Hadoop有很大提升,2014年10月,Spark完成了一个Daytona Gray类别的Sort Benchmark测试,排序完全是在磁盘上进行的,与Hadoop之前的测试的对比结果如表格所示:&br&&img src=&/029ab6e670fa8fab5fb3a59_b.jpg& data-rawwidth=&696& data-rawheight=&412& class=&origin_image zh-lightbox-thumb& width=&696& data-original=&/029ab6e670fa8fab5fb3a59_r.jpg&&(表格来源: &a href=&///?target=http%3A///blog//spark-officially-sets-a-new-record-in-large-scale-sorting.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Spark officially sets a new record in large-scale sorting&i class=&icon-external&&&/i&&/a&)&br&从表格中可以看出排序100TB的数据(1万亿条数据),&b&Spark只用了Hadoop所用1/10的计算资源,耗时只有Hadoop的1/3&/b&。&br&&br&&br&Spark的优势不仅体现在性能提升上的,Spark框架为批处理(Spark Core),交互式(Spark SQL),流式(Spark Streaming),机器学习(MLlib),图计算(GraphX)提供一个统一的数据处理平台,这相对于使用Hadoop有很大优势。&br&&br&&img src=&/c9c37ed908b6d7c6a1d98787efd649f7_b.jpg& data-rawwidth=&916& data-rawheight=&385& class=&origin_image zh-lightbox-thumb& width=&916& data-original=&/c9c37ed908b6d7c6a1d98787efd649f7_r.jpg&&(图片来源:&a href=&///?target=https%3A////4-reasons-why-spark-could-jolt-hadoop-into-hyperdrive/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&//4&/span&&span class=&invisible&&-reasons-why-spark-could-jolt-hadoop-into-hyperdrive/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&)&br&&br&按照Databricks的连城的说法是&b&One Stack To Rule Them All&/b&&br&&br&特别是在有些情况下,你需要进行一些ETL工作,然后训练一个机器学习的模型,最后进行一些查询,如果是使用Spark,你可以在一段程序中将这三部分的逻辑完成形成一个大的&b&有向无环图(DAG)&/b&,而且Spark会对大的有向无环图进行整体优化。&br&&br&例如下面的程序:&br&&div class=&highlight&&&pre&&code class=&language-text&&val points = sqlContext.sql(
“SELECT latitude, longitude FROM historic_tweets”)
val model = KMeans.train(points, 10)
sc.twitterStream(...)
.map(t =& (model.closestCenter(t.location), 1))
.reduceByWindow(“5s”, _ + _)
&/code&&/pre&&/div&(示例来源:&a href=&///?target=http%3A//www.slideshare.net/Hadoop_Summit/building-a-unified-data-pipeline-in-apache-spark& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&slideshare.net/Hadoop_S&/span&&span class=&invisible&&ummit/building-a-unified-data-pipeline-in-apache-spark&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&)&br&这段程序的第一行是用Spark SQL 查寻出了一些点,第二行是用MLlib中的K-means算法使用这些点训练了一个模型,第三行是用Spark Streaming处理流中的消息,使用了训练好的模型。&br&&br&&b&Lambda Architecture&/b&&br&Lambda Architecture是一个大数据处理平台的参考模型,如下图所示:&br&&img src=&/2a4e99ec84da2c367f883af2313c16dd_b.jpg& data-rawwidth=&800& data-rawheight=&453& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/2a4e99ec84da2c367f883af2313c16dd_r.jpg&&(图片来源: &a href=&///?target=https%3A///developercentral/lambda-architecture& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Lambda Architecture&i class=&icon-external&&&/i&&/a&)&br&其中包含3层,Batch Layer,Speed Layer和Serving Layer,由于Batch Layer和Speed Layer的数据处理逻辑是一致的,如果用Hadoop作为Batch Layer,而用Storm作为Speed Layer,你需要维护两份使用不同技术的代码。&br&&br&而Spark可以作为Lambda Architecture一体化的解决方案,大致如下:&br&&ul&&li&Batch Layer,HDFS+Spark Core,将实时的增量数据追加到HDFS中,使用Spark Core批量处理全量数据,生成全量数据的视图。,&/li&&li&Speed Layer,Spark Streaming来处理实时的增量数据,以较低的时延生成实时数据的视图。&/li&&li&Serving Layer,HDFS+Spark SQL(也许还有BlinkDB),存储Batch Layer和Speed Layer输出的视图,提供低时延的即席查询功能,将批量数据的视图与实时数据的视图合并。&/li&&/ul&&b&总结&/b&&br&如果说,MapReduce是公认的分布式数据处理的低层次抽象,类似逻辑门电路中的与门,或门和非门,那么Spark的RDD就是分布式大数据处理的高层次抽象,类似逻辑电路中的编码器或译码器等。&br&&br&RDD就是一个分布式的数据集合(Collection),对这个集合的任何操作都可以像函数式编程中操作内存中的集合一样直观、简便,但集合操作的实现确是在后台分解成一系列Task发送到几十台上百台服务器组成的集群上完成的。最近新推出的大数据处理框架Apache Flink也使用数据集(Data Set)和其上的操作作为编程模型的。&br&&br&由RDD组成的有向无环图(DAG)的执行是调度程序将其生成物理计划并进行优化,然后在Spark集群上执行的。Spark还提供了一个类似于MapReduce的执行引擎,该引擎更多地使用内存,而不是磁盘,得到了更好的执行性能。&br&&br&那么Spark解决了Hadoop的哪些问题呢?&br&&ul&&li&抽象层次低,需要手工编写代码来完成,使用上难以上手。&/li&&ul&&li&=&基于RDD的抽象,实数据处理逻辑的代码非常简短。。&/li&&/ul&&li&只提供两个操作,Map和Reduce,表达力欠缺。&/li&&ul&&li&=&提供很多转换和动作,很多基本操作如Join,GroupBy已经在RDD转换和动作中实现。&/li&&/ul&&li&一个Job只有Map和Reduce两个阶段(Phase),复杂的计算需要大量的Job完成,Job之间的依赖关系是由开发者自己管理的。&/li&&ul&&li&=&一个Job可以包含RDD的多个转换操作,在调度时可以生成多个阶段(Stage),而且如果多个map操作的RDD的分区不变,是可以放在同一个Task中进行。&/li&&/ul&&li&处理逻辑隐藏在代码细节中,没有整体逻辑&/li&&ul&&li&=&在Scala中,通过匿名函数和高阶函数,RDD的转换支持流式API,可以提供处理逻辑的整体视图。代码不包含具体操作的实现细节,逻辑更清晰。&/li&&/ul&&li&中间结果也放在HDFS文件系统中&/li&&ul&&li&=&中间结果放在内存中,内存放不下了会写入本地磁盘,而不是HDFS。&/li&&/ul&&li&ReduceTask需要等待所有MapTask都完成后才可以开始&/li&&ul&&li&=& 分区相同的转换构成流水线放在一个Task中运行,分区不同的转换需要Shuffle,被划分到不同的Stage中,需要等待前面的Stage完成后才可以开始。&/li&&/ul&&li&时延高,只适用Batch数据处理,对于交互式数据处理,实时数据处理的支持不够&/li&&ul&&li&=&通过将流拆成小的batch提供Discretized Stream处理流数据。&/li&&/ul&&li&对于迭代式数据处理性能比较差&/li&&ul&&li&=&通过在内存中缓存数据,提高迭代式计算的性能。&/li&&/ul&&/ul&&br&因此,Hadoop MapReduce会被新一代的大数据处理平台替代是技术发展的趋势,而在新一代的大数据处理平台中,Spark目前得到了最广泛的认可和支持,从参加Spark Summit 2014的厂商的各种基于Spark平台进行的开发就可以看出一二。
Hadoop 首先看一下Hadoop解决了什么问题,Hadoop就是解决了大数据(大到一台计算机无法进行存储,一台计算机无法在要求的时间内进行处理)的可靠存储和处理。 HDFS,在由普通PC组成的集群上提供高可靠的文件存储,通过将块保存多个副本的办法解决服务器或硬…
讲一个效果很震撼的&br&现在的机器人运动控制,基本上都是针对某一个或某一类动作进行设计,以仿人机器人为例,一个踢球动作就有上百上千篇学术论文在研究。&br&而人工智能机器学习这些,在实际机器人运动控制、规划中的使用还基本上局限于学习个模型参数程度的水平。&br&用算法根据环境和机器人状态自动生成动作?似乎还很遥远。&br&直到我看到这个研究:&br&CONTACT-INVARIANT TRAJECTORY OPTIMIZATION&br&一句话,对于任意结构的机器人,任意初始姿态位置,只要指定了末状态,算法可以自动生成符合物理规律的,机器人全身动作。&br&不只是走两步,站起来这么简单,甚至有爬楼梯、倒立、两人配合攀登等等。。&br&&img src=&/57eed0a5b4_b.jpg& data-rawwidth=&281& data-rawheight=&256& class=&content_image& width=&281&&&img src=&/51c84c4c092fef0a3155bd6adf0c4907_b.jpg& data-rawwidth=&241& data-rawheight=&267& class=&content_image& width=&241&&&br&看视频更直观:&a href=&///?target=http%3A//homes.cs.washington.edu/%7Etodorov/highlight/MordatchSIGGRAPH12.mp4& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&homes.cs.washington.edu&/span&&span class=&invisible&&/~todorov/highlight/MordatchSIGGRAPH12.mp4&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&甚至转笔这种动作:&a href=&///?target=http%3A//homes.cs.washington.edu/%7Etodorov/highlight/MordatchSCA12.mp4& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&homes.cs.washington.edu&/span&&span class=&invisible&&/~todorov/highlight/MordatchSCA12.mp4&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&img src=&/16da2a8a59a00d9ded567_b.jpg& data-rawwidth=&319& data-rawheight=&225& class=&content_image& width=&319&&&br&这个教授的主页&a href=&///?target=http%3A//homes.cs.washington.edu/%7Etodorov/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Emo Todorov&i class=&icon-external&&&/i&&/a& 保加利亚人,高中是数学和信息的双料国际金牌。。。&br&&br&想听原理的话,简单说来,用轨迹优化,特殊之处是用加附加变量的方式把各个接触面的接触情况也编码进整个模型的“状态”里,并使用“软化” 的接触动力学模型,把运动规划这个本来包含很多不连续处(比如撞击,其实任何接触面的变化都意味着系统动力学特性的突变)的问题表述成一个连续、无约束的凸优化问题。详情去看论文。&br&&br&虽然严格说来算法对实际环境做了不少假设和简化,但它解决的问题还是非常有价值,给人以启发的。&br&&br&/***************更新***************/&br&1. 感谢许多知友的提醒,这个其实不算控制算法,属于运动规划算法。算法得到的轨迹往机器人身上用的时候,需要的是控制算法来聪明地利用反馈信息,既实现动作又维持机器人平衡等要求。&br&2. 该实验室在此项目上正在做的就是做实时控制器。已经发表的成果是通过同时对多个不同的模型进行轨迹优化,提高轨迹的鲁棒性(想法是,如果一条轨迹在仿真中对10个质量分布略不同的机器人都能稳定,那实际的机器人应当处于这10个情况中间的某处,也稳定),在线跑时用一个简单的线性反馈控制器。实现了DARwIn上幅度很大的动作,比如一步转身90度之类。论文连接:&br&&a href=&///?target=http%3A//homes.cs.washington.edu/%7Etodorov/papers/MordatchICRA15.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&homes.cs.washington.edu&/span&&span class=&invisible&&/~todorov/papers/MordatchICRA15.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&3. 我微信在写机器人新闻,手动翻译国外最新消息,懒得看英文新闻又对机器人行业感兴趣的童鞋欢迎关注:微信号GoRobotics&br&&img src=&/19eec567b59df44e71cdea4c9341d91c_b.jpg& data-rawwidth=&417& data-rawheight=&422& class=&content_image& width=&417&&
讲一个效果很震撼的 现在的机器人运动控制,基本上都是针对某一个或某一类动作进行设计,以仿人机器人为例,一个踢球动作就有上百上千篇学术论文在研究。 而人工智能机器学习这些,在实际机器人运动控制、规划中的使用还基本上局限于学习个模型参数程度的水…
&blockquote&&p&“世之奇伟、瑰怪、非常之观,常在于险远,而人之所罕至焉,故非有志者不能至也。”&/p&&p&
----王安石《游褒禅山记》&/p&&/blockquote&前三章,前三章是个什么概念呢?大概就是为了后面的内容打基础吧!你正要步入SICP中最神奇的领域,如果你因为读完前三章“没有什么感觉”,那么就亏大发了!&br&&br&&img src=&/2ef2cff9ee581eab55e86b5_b.jpg& data-rawwidth=&640& data-rawheight=&640& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/2ef2cff9ee581eab55e86b5_r.jpg&&&br&About Me&br&&a href=&///?target=https%3A///DeathKing/Learning-SICP& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&SICP公开课&i class=&icon-external&&&/i&&/a&中文化组织者及主要译者,Learning-SICP群主,最近正以SICP书后习题为基础,发布一些小&a href=&///?target=http%3A//deathking.github.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Quiz&i class=&icon-external&&&/i&&/a&。&br&&br&&blockquote&&b&TL; DR&/b&&br&&b&Q: &/b&SICP是讲Scheme或Lisp么?&br&&b&A:&/b& #f.&br&&b&Q:&/b& SICP是讲软件工程么?&br&&b&A: &/b&部分,但并非全部。主要是模块化和黑盒抽象,计算机中两大主要基本思想。SICP关心的是:“当系统复杂度爆炸时(或者在此之前),我们如何通过有效的方法和手段去控制系统的复杂度?”&br&&b&Q:&/b& SICP是讲编译原理么?&br&&b&A:&/b& 部分,另外,如同书名说描述的那样,SICP中的“编译”都是“解释”,这种解释的行为,无外乎就是用一种机器的计算行为去模拟另一种机器。&/blockquote&&br&如果笼统地概括SICP全书的主题,那么不外乎“&b&抽象&/b&”二字。SICP全书不过五章,其中有三章的标题就直接带有“抽象”这个字眼,其余两章则是暗含了“抽象”这个主题,不妨让我们来看下这五章的名称:&br&&br&&ol&&li&&b&构造过程抽象&/b&(Building Abstractions with Procedures)&br&&/li&&li&&b&构造数据抽象&/b&(Building Abstractions with Data)&/li&&li&&b&模块化、对象和状态&/b&(Modularity, Objects, and State)&/li&&li&&b&元语言抽象&/b&(Meta-Linguistic Abstraction)&br&&/li&&li&&b&寄存器机器里的计算&/b&(Register Machine' Model of Control)&br&&/li&&/ol&&br&那我们为什么要去建立抽象呢?很简单:&b&控制复杂度&/b&。正如两位作者在第一版前言里面写的那样:&br&&br&&blockquote&……其次,我们相信,在这一层次的课程里,最基本的材料并不是特定程序设计语言的语法,不是有效计算某种功能的巧妙算法,也不是算法的数学分析或者计算的本质基础,而是一些能够用于&b&控制大型软件系统的智力复杂性的技术&/b&。&br&……他们应该掌握了&b&控制大型系统中的复杂性&/b&的主要技术……他们应该知道在什么时候哪些东西不需要去读,哪些东西不需要去理解……&br&……我们在适当的时候隐藏起一些细节,通过创建抽象去控制复杂性。我们通过建立约定的界面,以便能以一种“混合与匹配”的方式组合起一些标准的、已经很好理解的片段,去控制复杂性。我们通过建立一些新的语言去描述各种设计,每种语言强调设计中一个特定方面并降低其他方面的重要性,以&b&控制复杂度&/b&。&/blockquote&&br&实际上,即时是看似非常简单的前三章,也有蕴含着非常深刻的思想:&br&&br&&ol&&li&牛顿迭代法求平方根,不但介绍了如何通过不断迭代来改进猜测,用于求取某数的平方根,这种数学意义上的&b&计算方法&/b&,同时也介绍了&b&高阶函数&/b&在程序设计中的应用。&/li&&li&对递归的深入讨论,纠正了我们对于递归效率低下的错误认知。实际上,尾递归优化可以使尾递归调用在常量空间内做迭代计算。(William Clinger博士在&a href=&///?target=http%3A///v_show/id_XNjY0ODkxNjky.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Compiler Optimization for Symbolic Languages&i class=&icon-external&&&/i&&/a&中引征Guy Steel的话:“并不是函数调用造成压栈,是参数求值造成压栈。”)&/li&&li&在对高阶过程的讨论中,观察到了计算过程有很多重复的模式,于是提出了&b&“提取公共模式”&/b&这种思想,这也是设计模式里面模板方法的根本理论基础。&/li&&li&在数据抽象的讨论中,介绍了如何将基本元素构造成复杂元素,如何做&b&通用算术(Generic Arithmetic)&/b&及&b&类型分派&/b&,如何构造抽象屏障。当你接触到&b&邱奇数&/b&后,你会惊异于竟然“数据也可以是过程”。甚至你认为通过cons构造出来的序对,应该是某种数据结构,但它其实只是一个过程(见练习2.4)!&/li&&li&在第三章的讨论中,深入研究了&b&赋值&/b&所带来的问题,&b&并发&/b&带来的问题,并且研究了一个非常有用的、具有&b&惰性&/b&的数据结构:“&b&流&/b&”。&/li&&li&第三章是承前启后的,在第一章中引入了求值的&b&代换模型&/b&,而在这一章中正式引入求值的&b&环境模型&/b&,为第四章创建元语言解释器打下基础。第二,由于引入了赋值,第三章额外强调黑盒化,因此可以看到很多面向对象技术的雏形,如&b&消息传递&/b&。&/li&&/ol&&br&上面只是粗略的概括了一下前三章的部分内容,如果你要深入挖掘,你会发现前三章蕴含了更多的财富。当你爬过了前三章,你会发现一片新的天地。如果说前三章侧重于&b&“软件工程”&/b&,那么说四、五章在讲&b&“编译原理”&/b&,似乎也不为过。&br&&br&&blockquote&&p&有一种非常强有力的设计策略,特别适合用于构造那类模拟真实物理系统的程序,那就是基于被模拟系统的结构去设计程序的结构。对于有关的物理系统里的每个对象,我们构造起一个与之对应的计算对象;对该系统里的每种活动,我们在自己的计算系统里定义一种符号操作。采用这一策略时的希望是,
在需要针对系统中的新对象或者新活动扩充对应的计算模型时,我们能够不必
对程序做全面的修改,而只需要加入与这些对象或者动作相对应的新的符号对象。如果我们在系统的组织方面做得很成功,那么在需要添加新特征或者排除旧东西里的错误时,就只需要在系统里的一些小局部中工作。 &/p&&/blockquote&&br&作者在第四章伊始就以简明而独到的语言描述了为什么我们要创建元语言抽象。在第四章中,也是SICP最为闪光熠熠的一章,显示介绍了如何用Lisp来模拟一台Lisp求值器。在这一章中,或者说就在4.1节,作者描述了如何用Scheme创建一个简易的Scheme核心解释器,一旦你了解了Scheme的求值原理,像&b&词法闭包&/b&、&b&代码即数据&/b&、&b&邱奇数&/b&等一些列听起来很“玄乎”的概念也就豁然开了了!第四章的后面扩展了Lisp的求值规则,作者把他们称作“Scheme变形”,引入了&b&amb(非确定性计算)&/b&和&b&惰性求值&/b&。最后还介绍了如何用Scheme来模拟一种逻辑程序设计的语言。&br&&br&&blockquote&求值器决定了一个程序设计语言中各种表达式的意义,而它本身也不过就是另一个程序。&br&&/blockquote&&br&一旦认识到这点,你就会发现,所有“解释”或“编译”的行为,无外乎就是&b&“用一种机器”去模拟“另一种机器的行为”&/b&,比如用DFA通过(NFA的)子集构造去模拟NFA[谢 &a data-hash=&cf205dceb97c3f80b84ad& href=&///people/cf205dceb97c3f80b84ad& class=&member_mention& data-editable=&true& data-title=&@吕子熏& data-tip=&p$b$cf205dceb97c3f80b84ad& data-hovercard=&p$b$cf205dceb97c3f80b84ad&&@吕子熏&/a& 兄提醒,修改了措辞]。有了这个思想,于是就有了第五章:寄存器机器里的计算。&br&&br&SICP在书中介绍了许多有趣的系统:约束传播、编译器与求值器的互联、废料收集、类型的层次系统、延时求值等。SICP是一本奇书,细细评味,你一定能发现之中的醇香。&br&&br&祝愿你能早日突破层层括号的束缚,找到住在计算机内的神灵。
“世之奇伟、瑰怪、非常之观,常在于险远,而人之所罕至焉,故非有志者不能至也。” ----王安石《游褒禅山记》前三章,前三章是个什么概念呢?大概就是为了后面的内容打基础吧!你正要步入SICP中最神奇的领域,如果你因为读完前三章“没有什么感觉”,那么…
已有帐号?
无法登录?
社交帐号登录
206 人关注
744 人关注
224 条内容
361 人关注
100 条内容
1954 人关注
1146 条内容
105 人关注

我要回帖

更多关于 atom nodejs 自动补全 的文章

 

随机推荐