webp 吹了那么多年,为什么webp 图片格式 兼容性

相关TAG标签:
昵称:&&&&
?()?()?()?()?()?()?()?()?()?()?()?()?()?()?()?()?()?()?()?()
??????????
软件直销网消息,&移动微视频应用&是近年来新近流行的基于移动智能终端的全..&
&&&&& 2月14日,酷我音乐官方正式发布了酷我听听语音搜索版手机音乐播..&
版权所有 上海晋财企业投资咨询有限公司
Copyright? soft568.com
All Rights ReservedVuejs webp图片支持,插件开发过程~
Vuejs webp图片支持,插件开发过程~
本人已经使用vue.js半年多了,在做一些Html5页面的时候发现很多页面都是图片组成的,如果能有效的压缩图片的体积那么整个项目体积就会减少很多,这是为什么写这个简单东西的起点。
百度百科上已经讲清楚在保持原画质的情况呀体积可以压缩到原来的60%这是很牛逼的一件事。看看webp的兼容情况,下图是caniuse上面最新的webp支持情况
webp兼容情况
兼容情况还是不那么乐观,不过chrome和安卓阵营已经全部支持。所以我还是做了这件事。
Vue.js 的自定义指令系统十分强大是我做这件事的根本原因之一,所以我的设想是在一个指令中传入图片链接,然后在页面渲染的时候根据浏览器是否支持webp格式的图片选择下载那个图片,这里就需要判断浏览器是否支持webp了,这里我用到的是canvas方法,代码如下
var canUseWebp = (function() {
var elem = document.createElement('canvas');
if (!!(elem.getContext && elem.getContext('2d'))) {
return elem.toDataURL('image/webp').indexOf('data:image/webp') === 0;
这时候就非常简单了指令在update的时候根据是否支持然后选择不同的图片
function update(el, option) {
var attr = option.arg || 'src';
if (el.tagName.toLowerCase() === 'img' && option.value) {
el.setAttribute(attr, option.value);
然而事情的这个时候发现一些小的图标不见了,原来我的webpack配置中设置了小于10k的图片使用base64编码,
所以最终我的更新代码是这样的
function update(el, option) {
var attr = option.arg || 'src';
if (el.tagName.toLowerCase() === 'img' && option.value) {
if (option.value.indexOf('data:image') & 0) {
var tmp = option.value.substring(0, option.value.lastIndexOf('.')) + '.webp';
el.setAttribute(attr, canUseWebp ? tmp : option.value);
el.setAttribute(attr, option.value);
这个时候vue.js 2.0发布了。我有针对 2.0版本做了支持,由于我的指令非常简单,所以代码很轻松
var isVueNext = Vue.version.split('.')[0] === '2';
if (isVueNext) {
Vue.directive('webp', function(el, binding) {
update(el, {
arg: binding.arg,
value: binding.value
Vue.directive('webp', {
bind: function() {},
update: function(val, old) {
update(this.el, {
arg: this.arg,
value: val
unbind: function() {}
这样我的vue-webp指令就算完成了。
只有指令可不行,每次都要自己生成一份webp格式的图片,这太不友好了。我有查找一番,发现一个webp-loader可以在webpack打包和dev的时候自动生成相应的webp文件,太好了。使用原作者的webp-loader发现文件的hash不一样,我又用imagemin最新版本升级了一下,上传到npm叫webpn-loader(原谅我不会命名),
具体使用方法可以参考我的 项目
谢谢大家,看到这里。欢迎各种star
一个在前端路上越走越远的猿~
javascript 正则表达式总结 - 前端 - 掘金为什么要使用正则表达式 正则表达式通过由普通字符和特殊字符组成的文字模板完成对字符串的校验,搜索,替换。在javascript中类似这样 ... 平时自己项目中用到的 CSS - 掘金css有些属性容易忘记,半天不写就...
内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 UI组件 element ★13489 - 饿了么出品的Vue2的web UI工具套件 Vux ★8133 - 基于Vue和WeUI的组件库 iview ★6634 - 基于 Vuejs 的开源 U...
目录 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 UI组件 element ★13489 - 饿了么出品的Vue2的web UI工具套件 Vux ★8133 - 基于Vue和WeUI的组件库 iview ★6634 - 基于 Vuejs 的开源 U...
转载 :OpenDiggawesome-github-vue 是由OpenDigg整理并维护的Vue相关开源项目库集合。我们会定期同步OpenDigg上的项目到这里,也欢迎各位提交项目给我们。 如果收录的项目有错误,可以通过issue反馈给我们。这里的项目Star数不是实时...
无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到这篇好的文章:http://www.jianshu.com/p/42e11515c10f 写在前面的话阅读本文之前,先看下面这个webpack的配置文件,如果每...
今天在知乎上受邀了这样一个问题:老公和好朋友出轨了,虽然真的不想再提好朋友三个字,可这确实是事实。一直都是没有心眼的人,别人对我好,我就一定要加倍对别人好。可没有想到的是,自己的老公居然和自己的朋友在一起,同时背叛了我。渣男甚至为了小三提出了离婚,并且动了手。同在一个办公室...
01 周末,与小兵同学窝在家里。从超市回来,看了看昨天被小兵同学弄乱的家里,电脑、平板、还有各种线,散落在二十平米的小屋里。 瞬间怒火中烧,“你能不能把这些放好?” “看看看,又开始说我了,说我说成习惯了吧。”小兵同学像个孩子一样的,嘟囔着嘴。好脾气的他最近也开始有点抵不住...
“其实我也不懂,我现在根本不想谈感情,你说我喜欢漂亮的吗,嗯,也喜欢,你说我喜欢长相一般的吗……” 当然也喜欢,喜欢的不行的人不就是一个普普通通的人吗?! 只是,人生交错,你们已经踏不上去往一个目的地的车了。你可以不懂感情的事,但是应该接受你哪怕恋了十年、二十年甚或一生,你...
我这辈子最受不了的两件事,一件是“离开”,另一件就是“背叛”。 上高中时候寄宿学校,每次从家离开,都有一种“沉香含泪别母”的情愫,好像这一别,殊不知何年何月何日才能相见,而只是每隔一个星期,我就又和母亲相见了。 毕业的时候,大家晃动着酒杯,仿若这一别,就是生死离别,这顿酒,...
你有没有这样的体验 被陌生人的善意温暖 如果你曾被温柔对待 请你将这份温柔传递 --------饭二 有人感慨世界冷漠,人们自顾不暇 无法腾出手来多给世界一点爱 我不同意 这篇是一些并不有力的反驳 集结饭二粉丝和朋友的分享 那些生命里偶遇过的陌生人只是短暂停留就走向远方留下...&p&作为大一C语言的老师,我来简单回答下吧。实际上班级同学的大作业,都要求500行以上的代码。下面是之前年级同学做的一些游戏作业效果:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-b8a704ac792c433fecaf7d_b.png& data-caption=&& data-rawwidth=&939& data-rawheight=&598& class=&origin_image zh-lightbox-thumb& width=&939& data-original=&https://pic2.zhimg.com/v2-b8a704ac792c433fecaf7d_r.png&&&/figure&&p&&br&&/p&&p&下面是对应的一些作业视频集锦:&/p&&p&2014级: &a href=&//link.zhihu.com/?target=http%3A//pan.baidu.com/s/1EVmX4& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&pan.baidu.com/s/1EVmX4&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&2015级: &a href=&//link.zhihu.com/?target=http%3A//pan.baidu.com/s/1o75mduy& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&pan.baidu.com/s/1o75mdu&/span&&span class=&invisible&&y&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&2016级:&a href=&//link.zhihu.com/?target=https%3A//pan.baidu.com/s/1nuXHXtZ& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&pan.baidu.com/s/1nuXHXt&/span&&span class=&invisible&&Z&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&我的教学思路,是讲较少的语法,只讲必须用到的规范性语法知识。学数组前就带着同学们step by step,用printf输出实现打飞机、flappy bird、反弹球等游戏,大概是这样的效果:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-f70bb104db1c750f4a628fa_b.png& data-caption=&& data-rawwidth=&390& data-rawheight=&399& class=&content_image& width=&390&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-af1aebe3d1a7beaa28edd695_b.png& data-caption=&& data-rawwidth=&357& data-rawheight=&381& class=&content_image& width=&357&&&/figure&&p&讲完数组后,可以利用更复杂的数据结构,进一步改进上面三个经典的小游戏,然后可以实现贪吃蛇、生命游戏等更复杂的游戏:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-441f0142878eaf54fc0f_b.png& data-caption=&& data-rawwidth=&459& data-rawheight=&417& class=&origin_image zh-lightbox-thumb& width=&459& data-original=&https://pic3.zhimg.com/v2-441f0142878eaf54fc0f_r.png&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-a0dbe39dcf1b6c405813e_b.png& data-caption=&& data-rawwidth=&266& data-rawheight=&459& class=&content_image& width=&266&&&/figure&&p&&br&&/p&&p&再往下,教同学们学习一个简单的图形交互函数库:EasyX(&a href=&//link.zhihu.com/?target=http%3A//www.easyx.cn/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&首页 -- EasyX Library for C++&i class=&icon-external&&&/i&&/a&),可以将上面的小游戏做到图形界面、鼠标操作等。类似这样:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-eb2cdd7c5d59a825b31d_b.png& data-caption=&& data-rawwidth=&282& data-rawheight=&463& class=&content_image& width=&282&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-8f9adf5d76b77f441cd06_b.png& data-caption=&& data-rawwidth=&365& data-rawheight=&508& class=&content_image& width=&365&&&/figure&&p&&br&&/p&&p&然后,再讲C语言的后续语法知识,比如指针用在动态数组、字符串控制得分显示、结构体改进数据结构、文件用于游戏存档,等等。每讲一个知识点,都回过头去用于改进之前做的小游戏。也会介绍一些SVN这样的工具,便于同学们进行版本管理、团队合作。&/p&&p&&br&&/p&&p&大家学习的过程,可以参考这个思路,step by step逐步地来实现,一点一点地加上复杂的内容,会相对容易些,也更有成就感。另外,游戏的框架可以事先确定,避免出现大的游戏流程错误。&/p&&p&&br&&/p&&p&最后,下面是2016级同学的游戏大作业题目,期待这一届的同学有更好的作品。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-0f10fbcfc04b_b.png& data-caption=&& data-rawwidth=&998& data-rawheight=&549& class=&origin_image zh-lightbox-thumb& width=&998& data-original=&https://pic4.zhimg.com/v2-0f10fbcfc04b_r.png&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&------------------------------------------------------------------------------------&/p&&p&补充:&/p&&p&&br&&/p&&p&没有想到有这么多的同学、朋友对这种教学方式感兴趣,非常感谢大家的支持。之前我录过一个小视频,利用数组函数开发空战游戏的原型。感兴趣的同学可以看下,应该会对这个教学方法有个直观的了解,并可以上手改进: &a href=&//link.zhihu.com/?target=http%3A//pan.baidu.com/s/1dFDVqcp& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&pan.baidu.com/s/1dFDVqc&/span&&span class=&invisible&&p&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&目前这种教学方式也还是在不断的迭代完善中,可能会到下一个教学年度基本完善,同步录制相应的视频,撰写教材出版,也欢迎大家多提宝贵意见。&/p&&p&&br&&/p&&p&另外,我觉得比我编程厉害、讲的好的老师有很多,这种讲法可能只是讨了一个同学们对开发游戏感兴趣的巧,不足之处还请大家不吝赐教。谢谢!&/p&&p&&br&&/p&&p&12.28晚&/p&&p&&br&&/p&&p&------------------------------------------------------------------------------------&/p&&p&&br&&/p&&p&应很多同学的要求,准备写一些简单的教程,题目暂定为:做游戏,学编程(C语言) 。有问题欢迎大家指出,谢谢!&/p&&p&&br&&/p&&p&&a href=&https://zhuanlan.zhihu.com/c2game& class=&internal&&知乎专栏&/a&&/p&&p&&br&&/p&&p&12.29晚&/p&&p&&br&&/p&&p&------------------------------------------------------------------------------------&/p&&p&&br&&/p&&p&经过半年多的工作,采用以上教学思路的实践教材《C语言课程设计与游戏开发实践教程》终于出版了。&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-1c4dee343d52c95e72eb0_b.png& data-caption=&& data-rawwidth=&1079& data-rawheight=&736& class=&origin_image zh-lightbox-thumb& width=&1079& data-original=&https://pic1.zhimg.com/v2-1c4dee343d52c95e72eb0_r.png&&&/figure&&p&&br&&/p&&p&图书各章节主要内容如下:&/p&&p&第1章,学习printf、scanf、if-else、while、for语句后,进行弹跳小球、飞机游戏的开发,并介绍程序调试的方法与技巧。&/p&&p&第2章,学习函数后,利用函数封装及标准的游戏框架,进行飞机游戏、反弹球消方块、flappy bird的开发。&/p&&p&第3章,学习数组后,利用数组改进数据结构,实现生命游戏、反弹球消砖块、空战游戏、贪吃蛇的开发,并介绍SVN代码管理工具。&/p&&p&第4章,学习简单绘图工具,并进行多球反弹、实时钟表、反弹球消方块、鼠标交互的学习开发。&/p&&p&第5章,学习图片音乐素材的导入和使用,并进行flappy bird、飞机大战、行走小人、双人反弹球的开发学习。&/p&&p&第6章,利用后续语法知识进一步改进游戏程序,如指针创建动态数组、字符串控制得分显示、结构体改进数据结构、文件用于游戏存档等。实现了黑客帝国字符雨动画、互动粒子仿真、具有多界面和存档功能的飞机大战游戏。&/p&&p&第7章,利用游戏化学习的思路,学习C语言的两个知识难点:递归与链表。&/p&&p&第8章,介绍多个游戏开发实践案例:挖地小子、台球、太鼓达人、扫雷、蓝色药水、Rings、猪小弟、俄罗斯方块、通天魔塔、1010、炸弹人、口袋妖怪、大鱼吃小鱼。每个案例讲解了主体功能、实现思路。&/p&&p&&br&&/p&&p&图书的其他信息可以参考清华大学出版社上的介绍: &a href=&//link.zhihu.com/?target=http%3A//www.tup.tsinghua.edu.cn/booksCenter/book_.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&清华大学出版社-图书详情-《C语言课程设计与游戏开发实践教程》&i class=&icon-external&&&/i&&/a&&/p&&p&样章“第3章 应用数组的游戏开发”可在线阅读与下载: &a href=&//link.zhihu.com/?target=http%3A//www.tup.tsinghua.edu.cn/upload/books/yz/.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&tup.tsinghua.edu.cn/upl&/span&&span class=&invisible&&oad/books/yz/.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&图书附带的源代码可从百度网盘下载: &a href=&//link.zhihu.com/?target=http%3A//pan.baidu.com/s/1skGKbj3& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&pan.baidu.com/s/1skGKbj&/span&&span class=&invisible&&3&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&希望这本图书能对C语言初学者有所帮助,也欢迎大家多提宝贵意见,谢谢!&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&11.13&/p&&p&&br&&/p&&p&应一些同学的要求,把这学期上C语言编程课的讲课视频录制剪辑,上传到网易云课堂,感兴趣的朋友可以在线观看,欢迎多提宝贵意见。&/p&&p&&br&&/p&&p&MOOC视频链接:&a href=&//link.zhihu.com/?target=http%3A//study.163.com/course/introduction.htm%3FcourseId%3D& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&study.163.com/course/in&/span&&span class=&invisible&&troduction.htm?courseId=&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-c36a253fa124cffcb14149_b.jpg& data-caption=&& data-rawwidth=&1002& data-rawheight=&375& class=&origin_image zh-lightbox-thumb& width=&1002& data-original=&https://pic2.zhimg.com/v2-c36a253fa124cffcb14149_r.jpg&&&/figure&
作为大一C语言的老师,我来简单回答下吧。实际上班级同学的大作业,都要求500行以上的代码。下面是之前年级同学做的一些游戏作业效果: 下面是对应的一些作业视频集锦:2014级: 2015级: 201…
当你看完primer,甚至做了几个项目,自认为已经入门了的时候&br&忽然有一天你开始研究别人的代码。&br&当你看到别人写的template的时候;当你看到数字是全部要替换成宏的名字,英文要多长有多长的时候;struct全部用__attriburte__修饰的时候;运算都是位操作的时候;操作符都是重载的时候;网络都是并发缓冲线程池的时候;int只用int32_t声明的时候;继承不用普通的,各种多继承虚继承回调函数的时候;一个hello world也要写捕获异常的时候;中间一堆关键字extern,asm,auto,XXXXX_cast,volatile,explicit,register,template的时候。&br&顿时,那些整天写int,if,else,for的小程序猿开始怀疑人生了。
当你看完primer,甚至做了几个项目,自认为已经入门了的时候 忽然有一天你开始研究别人的代码。 当你看到别人写的template的时候;当你看到数字是全部要替换成宏的名字,英文要多长有多长的时候;struct全部用__attriburte__修饰的时候;运算都是位操作的时…
目前这个问题下最小的能在Windows系统上运行的Hello World是&a href=&https://www.zhihu.com/question//answer/& class=&internal&&Windows 上最小的“HelloWorld.exe”能有多小? - 潘安仁的回答&/a&,161Bytes,我看了他的答案后深受启发,在他的基础上更进一步,写出了97Bytes的Hello World。&br&先贴代码,注意在32位Windows系统上运行。(我只在WinXP32上运行通过)&br&ps:评论区有人指出,只能在WinXP上运行,XP之后的系统库的地址会变。&br&pss:将本回答最后一幅图片保存,后缀改成 .rar ,解压后也能获得程序。&br&4D5A4CC6C6F2C776F726C0B016AF5EA0CEB07CCCCCC1ECE8A4C0807C90EBFD07C90EBFDCC00CCCCCC00CCCCCCCC03&br&&br&————————————————分割线————————————————&br&为什么我的程序更小?&br&&a data-hash=&c3400f8fdbe15fb2c394f724dbbe0e0c& href=&//www.zhihu.com/people/c3400f8fdbe15fb2c394f724dbbe0e0c& class=&member_mention& data-editable=&true& data-title=&@潘安仁& data-hovercard=&p$b$c3400f8fdbe15fb2c394f724dbbe0e0c&&@潘安仁&/a& 的程序输出Hello World用了USER32的MessageBoxA,这个api看上去很好,毕竟'USER32'是6Bytes,而其他的库名如'kernel32'是8Bytes,所以调用USER32中的函数更短?&br&&br&错。因为载入PE文件时kernel32.dll和ntdll.dll会被自动载入,并且这两个库正常是卸不掉的,你可以试试FreeLibrary(GetModuleHandle(&kernel32&)),然后再用汇编代码强制调用kernel32的一个函数,正常运行有没有。所以如果调用kernel32的函数可以删去导入表,大大节省空间。&br&&br&那kernel32有什么输出函数可以输出Hello world?&br&有。WriteConsoleA(),写控制台。如果是同一系统,这个函数的位置应该是不变的,在Winxp系统中,这个函数地址是7C81C0ED。同时这个函数还要用到控制台输出句柄,用GetStdHandle(),地址7C810C89。这下程序就小了很多。&br&&br&————————————————分割线————————————————&br&下面是程序的总体思路:&br&&br&1.先写汇编代码&br&&div class=&highlight&&&pre&&code class=&language-text&&Data: db 'Hello world!'
call 7C810C89
call 7C81C0ED
&/code&&/pre&&/div&代码好长啊能不能缩短一些呢?我们注意到WriteConsoleA的最后两个参数都对我们无用,一个保存被写入的字节数,一个是保留参数,这种无用的东西就丢掉好了。于是变成了:&br&&div class=&highlight&&&pre&&code class=&language-text&&Data: db 'Hello world!'
call 7C810C89
call 7C81C0ED
&/code&&/pre&&/div&这样函数还能正常返回吗?当然能,我们没将数据压入栈不代表不能pop出东西来,至于pop出来的是什么、由此而产生栈平衡问题都不关我事。&br&&br&2.压缩出最小的文件头&br&我的程序没有其他外部命令,自然不需要导入表和导出表,节表也不需要,直接将代码写在文件头里,只需要DOS头、文件头和可选头。&br&这里就是 &a data-hash=&c3400f8fdbe15fb2c394f724dbbe0e0c& href=&//www.zhihu.com/people/c3400f8fdbe15fb2c394f724dbbe0e0c& class=&member_mention& data-editable=&true& data-title=&@潘安仁& data-hovercard=&p$b$c3400f8fdbe15fb2c394f724dbbe0e0c&&@潘安仁&/a&的神操作了,把PE头和DOS头重叠。&br&&figure&&img src=&https://pic2.zhimg.com/413b93d5c157f714bd8d0cc9a873ec25_b.jpg& data-rawwidth=&778& data-rawheight=&187& class=&origin_image zh-lightbox-thumb& width=&778& data-original=&https://pic2.zhimg.com/413b93d5c157f714bd8d0cc9a873ec25_r.jpg&&&/figure&如图,加载32位PE文件时,系统对dos头只读取开头的MZ标志和e_ifanew,中间的值可以随意填写,这样我们把NT头提到地址为4的地方去,将DOS头和NT头重叠。&br&大家也可以尝试其他的位置,其中4是最小的可行位置。&br&还有一处要注意的地方是我们的是控制台程序,所以Subsystem设为3。&br&图中是一个可运行的PE程序,运行后直接死循环。&br&可以看到这样的程序还有不少空位,我们可以把代码插进去。&br&&br&3.插入代码&br&文件头中的空白部分TimeDateSPointerToSymbolTNumberOfS都是无用且可以随意填写的,刚好12个字节,我们把&Hello world!&放进去。&br&剩下不少空位我们把代码也放进去,如果放不下就放一个jmp短跳,跳到下一个空位。&br&放好之后如图:&figure&&img src=&https://pic4.zhimg.com/5edd519e3ae8ae5b64aded23_b.jpg& data-rawwidth=&769& data-rawheight=&180& class=&origin_image zh-lightbox-thumb& width=&769& data-original=&https://pic4.zhimg.com/5edd519e3ae8ae5b64aded23_r.jpg&&&/figure&&br&图中我们放入代码后,还有不少空位,我都用0xCCh标记了出来。&br&&br&4.修剪&br&这样我们的程序已经很小了,它是124字节,那么怎么把它变成97字节呢?相信你也猜到了,把最后一堆零删掉就好了,PE文件载入时空白内存自动填零,这堆零我们是不需要的。&br&最后就是这样:&br&&figure&&img src=&https://pic3.zhimg.com/f11958e89bdf59887c6a_b.jpg& data-rawwidth=&774& data-rawheight=&164& class=&origin_image zh-lightbox-thumb& width=&774& data-original=&https://pic3.zhimg.com/f11958e89bdf59887c6a_r.jpg&&&/figure&&br&运行效果:&br&&figure&&img src=&https://pic1.zhimg.com/e29ce4ef615a60aa15dbe3d8_b.jpg& data-rawwidth=&668& data-rawheight=&431& class=&origin_image zh-lightbox-thumb& width=&668& data-original=&https://pic1.zhimg.com/e29ce4ef615a60aa15dbe3d8_r.jpg&&&/figure&输出了一行朴实无华的hello world,我们的程序还有不少空位,或许还可以把效果做炫酷一点,大家自己尝试。&br&&br&5.也学着做一个总结:&br&这个问题是13年提出来的,现在已经是16年了,在浮躁的社会里,这个问题或许早已被遗忘在尘埃里。我看到了这个问题,看到了前面大神的回答,我知道我可以做得比他更小,于是我开始着手尝试。我花了几天来学习PE结构,找出缩小程序的方法,思考余暇,我不禁疑惑,做这种事,做出这种程序有什么意义,我为什么要有一个这么小的Hello world?我硬盘差几字节吗?或许你也有一样的困惑,然而我们追求这一系列极限有什么意义呢?更高更快更强,是要回到狩猎时代吗?我想这一切无关乎这种浅薄的利益,它像是一种证明,证明自己的高度。它竖起了一座里程碑,并鼓励后来人一步一个脚印,继续向上,去到山顶上,去睥睨众生。如此之后,我们浮躁的社会里,或许有了一点没那么浮躁的东西。
目前这个问题下最小的能在Windows系统上运行的Hello World是,161Bytes,我看了他的答案后深受启发,在他的基础上更进一步,写出了97Bytes的Hello World。 先贴代码,注意在32位Windows系统上…
用C写了一个图形界面的2048游戏给老婆玩。&br&&br&老婆酷爱2048,于是在网上找PC版给她玩,结果网上的全是嵌入广告,怒写一个!&br&&br&为了方便开局,又增加了&b&随机开局&/b&的功能,直接从中途开始打,原始积累太慢了。&br&随时可以中断,游戏带&b&存档功能&/b&。&br&&figure&&img src=&https://pic1.zhimg.com/71d107e59eae152ee83bfc4_b.jpg& data-rawwidth=&416& data-rawheight=&638& class=&content_image& width=&416&&&/figure&&br&&br&&figure&&img src=&https://pic1.zhimg.com/d5bdfe1a413db_b.jpg& data-rawwidth=&416& data-rawheight=&638& class=&content_image& width=&416&&&/figure&&br&源码1000+行,完全是C+winAPI,没有MFC,没有QT……&br&界面是用windows API画的,按钮是用CreateWindow后自绘的,没有类,没有对象,完全面向过程编程……&br&&b&欢迎围观(源代码):&/b&&a href=&//link.zhihu.com/?target=https%3A//github.com/tomwillow/2048& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GitHub - tomwillow/2048: No Ads, More Advanced 2048 Game&i class=&icon-external&&&/i&&/a&&br&&br&补充:&br&有C的基础又想学习C+Win SDK编程的小伙伴读《Windows程序设计 第5版》就可以了,读到一半就可以写我这个东西了,欢迎大家与我交流。&br&&br&之前居然忘了百度云,现在传上游戏exe(由于Github上已经有代码了,CSDN的链接我就删掉了):&br&&b&想打游戏的点这里下载:&/b&&a href=&//link.zhihu.com/?target=http%3A//pan.baidu.com/s/1dEHEFCH& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&pan.baidu.com/s/1dEHEFC&/span&&span class=&invisible&&H&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&
用C写了一个图形界面的2048游戏给老婆玩。 老婆酷爱2048,于是在网上找PC版给她玩,结果网上的全是嵌入广告,怒写一个! 为了方便开局,又增加了随机开局的功能,直接从中途开始打,原始积累太慢了。 随时可以中断,游戏带存档功能。 源码1000+行,完全是C+…
其实很多人学编程都会遇到困难,我觉得其中一个根本原因是他们没搞明白学编程到底是学什么。&br&&br&编程不是一种知识,而是一门手艺。&br&&br&我们从小到大的学习都是学习知识,流程一般是课前看书预习,上课听讲,下课做作业,然后复习考试。但是学手艺可不是这么学的。&br&&br&我们先拿游泳举例,游泳不是知识,而是技能,也可以算门手艺吧。&br&需要预习吗?需要上课听讲吗?不需要,因为两岁小孩都能学会游泳,他们连话都不太会说呢,怎么可能听课预习呢。游泳是通过在水里的练习,教练手把手地传授动作,一点一点提高熟练度学会的。&br&&br&我们再来看看弹琴,学钢琴一定要有钢琴,音乐基础知识也是老师在练琴间隙传授的,并且一定会结合练习,另外练琴时间是很重要的,必须保证一定的练习量,有些理想远大的琴童练琴时间可以用惨无人道丧心病狂来形容。&br&&br&千万别把编程看作知识,计算机科学是知识,但是编程是手艺。&br&既然是手艺就要用学手艺的思路去学习。&br&&br&以动手练习为主,看书学习为辅,甚至极端点,初学的时候除了看必要的文档都可以不看书,等有了一定编程基础后再去看书,看完书立刻动手编程去验证书上的理论知识。&br&练习一定要循序渐进,把手艺分解成几个简单的动作,反复练习直到熟练,然后再把基本动作组合起来练习直到熟练。拿C语言举例,比如从认真写好一个Hello world开始,然后去熟悉 if
for while 等基本关键字,然后熟悉字符串操作,内存操作,练习查找 排序 二叉树等基本算法数据结构,然后学习一个小型Framework。。。。&br&找个师傅,手艺的一大特点就是自学是很慢的,而且容易走弯路,而有人手把手教要快得多,手艺有很多细节,实际操作经验,需要去体会感受的东西,这些细节书上基本不会有。&br&坚持做大量的练习,以代码行数为例,每年50000行左右是比较一般的练习量,有毅力的话可以挑战10万行。(有人说代码行数不代表什么,行数多不见得程序就对,写得好的程序代码很少blablabla,滚,去跟朗朗说去,告诉他其实不用练那么长时间琴。)&br&&br&回忆下自己当年是怎么学会骑自行车,学会游泳,学会打篮球的,按照那个思路去学编程,而不是用你学大学课程的思路去学编程。&br&&br&记住,编程是手艺,不是知识。&br&&br&======&br&最后再强调下,对编程能力本质最好的比喻就是弹琴。但是有了编程能力还不能算优秀的程序员,优秀的程序员是作曲家,他们不仅能想出优美的旋律,并且能弹奏出来,就像优秀的程序员不仅能想出优美的算法架构,而且能把它变成可执行代码。你很难想像作曲的人不会任何乐器。&br&&br&很多人的问题是想当作曲家却不肯下功夫去练琴。&br&&br&打个预防针,估计有人会举出反例说我就知道某某某作曲家不会乐器(其实真的有)。&br&我要说的是,等你成了公认的著名作曲家之后再说自己不会乐器,那你牛逼。&br&在成名之前就这么说那是煞笔。
其实很多人学编程都会遇到困难,我觉得其中一个根本原因是他们没搞明白学编程到底是学什么。 编程不是一种知识,而是一门手艺。 我们从小到大的学习都是学习知识,流程一般是课前看书预习,上课听讲,下课做作业,然后复习考试。但是学手艺可不是这么学的。…
C++是面向内存编程,Java是面向数据结构编程。&br&&br&C++里,内存是裸露的,可以拿到地址,随意徜徉,增了删了,没人拦你,等到跑的时候再崩给你看。&br&&br&Java里,能操作的都是设计好的数据结构,array有长度,String不可变,每一个都是安全的,在内存和程序员之间,隔着JVM,像是包住了边边角角的房间,随便小孩折腾,不会受伤。&br&&br&Java程序员是孩子,嚷嚷要这个那个,玩完了就丢,JVM是家长,买买买,还要负责收拾。有的孩子熊点,屋子很乱,收拾起来费劲,但房子还在。&br&&br&C++程序员是神,操纵着江河湖海,日月星辰,但能力越大,责任越大,万一新来的神比较愣,手一滑,宇宙就退出了。&br&&br&新手写C++,像是抱着一捆指针,在浩瀚的内存中裸奔。跑着跑着,有的针掉了,不知踪影,内存就泄露了;跑着跑着,突然被人逮住,按在地上打的error纷飞,内存就越界了;终于到了,舒了口气,把针插在脚下,念出咒语,&br&&br&“delete”&br&&br&系统就崩溃了。
C++是面向内存编程,Java是面向数据结构编程。 C++里,内存是裸露的,可以拿到地址,随意徜徉,增了删了,没人拦你,等到跑的时候再崩给你看。 Java里,能操作的都是设计好的数据结构,array有长度,String不可变,每一个都是安全的,在内存和程序员之间,…
&p&输出一个hello world?&br& 恩,首先我需要一个操作系统。 &br&于是我做了一个最小化的操作系统,&br&用上古机器语言,16进制的。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-c64dba99711fffc9e990d06_b.png& data-rawwidth=&657& data-rawheight=&607& class=&origin_image zh-lightbox-thumb& width=&657& data-original=&https://pic3.zhimg.com/v2-c64dba99711fffc9e990d06_r.png&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&1万多行,不过大多数都是0000000,保存为img格式。&/p&&p&都说了是最小化系统,所以就决定用软盘了!&br&于是买了软盘和软盘驱动。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-c8adcabb41a_b.jpg& data-rawwidth=&2276& data-rawheight=&1280& class=&origin_image zh-lightbox-thumb& width=&2276& data-original=&https://pic3.zhimg.com/v2-c8adcabb41a_r.jpg&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&把系统镜像烧到软盘里&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-573d5a7d12ede61d850ceed_b.png& data-rawwidth=&1290& data-rawheight=&2048& class=&origin_image zh-lightbox-thumb& width=&1290& data-original=&https://pic2.zhimg.com/v2-573d5a7d12ede61d850ceed_r.png&&&/figure&&p&&br&&/p&&p&烧录完成。&br&插上软驱,然后重启电脑。&br&开机设为软驱优先启动!&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-dabbbabfa33_b.jpg& data-rawwidth=&2276& data-rawheight=&1280& class=&origin_image zh-lightbox-thumb& width=&2276& data-original=&https://pic4.zhimg.com/v2-dabbbabfa33_r.jpg&&&/figure&
输出一个hello world? 恩,首先我需要一个操作系统。 于是我做了一个最小化的操作系统, 用上古机器语言,16进制的。 1万多行,不过大多数都是0000000,保存为img格式。都说了是最小化系统,所以就决定用软盘了! 于是买了软盘和软盘驱动。 把系统镜像烧到…
&p&你这属于 &b&生不逢时&/b& 的水平。&/p&&p&时间倒退20年,你这就是所谓软件高手,程序英雄,当年叱咤江湖的 求伯君,鲍岳桥,王志东,粱肇鑫等等,基本都是这个路数。&/p&&p&他们凭着过人的才智,对软件极大的热情,在只能接触到的有限的知识资料的情况下,把软件写到远超普通人的水平,凭着彪悍的个人能力一个人包办了需要一个团队来做的事情。&/p&&p&在那个时代就需要这样的人,所以历史进程选择了他们,给了他们成名的机遇,也给了相应的回报。&/p&&p&但是,时代变了,个人能力的作用在淡化,coding不再是核心竞争力。&/p&&p&(评论区预防针:coding不是核心竞争力的意思是能写好代码的人已经很多了,coding能力对于成功的贡献权重没以前那么大了,而不是说coding能力没有用了,即使写烂代码也能行的意思。)&/p&&p&这个时代,简单的需求,容易的事情,少量代码就能出成果的机会已经不复存在,如今软件互联网讲究的是团队协作,现在的软件复杂度很高,随便一个中等规模的互联网服务背后就涉及多种语言,2-4个操作系统平台,多达数十个基础开源框架,以及涉及到计算机科学和数学多个领域的算法。这些已经大大超过了一个人的能力范围。&/p&&p&野生程序员不是贬义,我上面提到的前辈们他们中很多也是野生的,我自己就是,众所周知我大学的专业是化学,编程纯粹是兴趣,都是自学的。从野生开始没问题,但是不能野生一辈子,人要与时俱进要顺应历史的进程。&/p&&p&如今能写好代码,找个中等收入的工作其实也不难,但是考虑到你对软件编程有如此高的热情应该不会只满足于得到一份养家糊口的收入的水平吧,应该对自己有更高的追求。&/p&&p&进一步的追求就是怎么把个人能力转化为团队能力,设计出可以维护,可测试,可优化,可多人并行开发,可快速迭代的软件架构,能在平衡好需求,效率和成本的同时为团队规划技术路线,在外部环境变化需求变化的时候,提前预知,带领团队做技术转型。&/p&&p&从你的言谈中我感觉到你这人性格有点小问题,这个问题会导致你很难融入团队,很难和别人协作。&/p&&p&这个问题并不是自大骄傲过于自信,实际上很多优秀的程序员都是这样的,聪明人的通病,真正的问题是你不知道怎么和别人互惠互利。&/p&&p&你从内心里希望别人承认你的水平高,技术牛,所以你展示自己的技术实力,希望别人通过理解你的代码和成果,对你的技术水平给予高度评价。&/p&&p&但是,此路不通,你采用这个方法是无法实现你的目的的,反而会让别人反感你。毕竟在知乎上还是有很多比你强得多的人的,引起了他们的反感,他们会纠出你的技术缺陷嘲讽一番,是不是很气啊?&/p&&p&这是为什么呢?因为你代码写的好,技术牛关别人什么事?你技术好又不能给别人带来任何收益。&/p&&p&技术水平要得到别人的承认,需要用你的技术做些有益于别人的事情。&/p&&p&比如,做技术分享培训,解决团队遇到的技术难题,辅导团队的新人尽快上手,别人问你问题的时候尽心尽力去回答,为团队争取到更多机会。&/p&&p&如果在知乎,展示成果的效果远不如回答问题,因为高质量的回答对别人是有帮助的,而你展示的技术成果对别人毫无用处。&/p&&p&最后,几个建议:&/p&&ol&&li&不要去做黑色产业,很多你这样的人会去做,虽然有些发了财,但是也有不少坐了牢。&/li&&li&出门找份工作,学习融入团队,学会协作,用自己技术做些有益于身边人的事情,你会获得快乐。&/li&&li&去旅游吧,去很远的地方,去地球另一端,见识了世界之大就会理解自己的渺小了。&/li&&/ol&&p&祝 新年快乐&/p&
你这属于 生不逢时 的水平。时间倒退20年,你这就是所谓软件高手,程序英雄,当年叱咤江湖的 求伯君,鲍岳桥,王志东,粱肇鑫等等,基本都是这个路数。他们凭着过人的才智,对软件极大的热情,在只能接触到的有限的知识资料的情况下,把软件写到远超普通人…
中国反病毒界有一位传奇人物。&br&&br&他写了一个杀毒软件,装在软盘里卖,一张软盘卖280元。&br&&br&为防止盗版,他对软盘做了加密,一旦把这个杀毒软件拷贝到别的软盘,就无法执行。&br&&br&但是他越是这样用严密的方式加密,就越引来各界高手对解密的跃跃欲试,所以他不断更改他的加密技术,从EXE加壳,到特殊磁道写入,再到软盘片激光打孔,再到磁头直接控制技术(让磁头运行在两个磁道中间)。&br&&br&可以说,当时整个中国就是他一个人在跟加密解密界斗,而且从未落下风。&br&&br&1997年,他身家过亿,公司只有不到5个人。&br&&br&他叫王江民,残疾人,小学文化,前半生穷困潦倒。38岁开始学计算机,kv100杀毒软件是他用汇编语言写的。&br&&br&&br&&br&你今年22岁,你问你现在学c语言算不算晚?
中国反病毒界有一位传奇人物。 他写了一个杀毒软件,装在软盘里卖,一张软盘卖280元。 为防止盗版,他对软盘做了加密,一旦把这个杀毒软件拷贝到别的软盘,就无法执行。 但是他越是这样用严密的方式加密,就越引来各界高手对解密的跃跃欲试,所以他不断更改…
由于我大一也陷入过迷茫,也走过一些弯路,那时候学不会直接记忆代码之类的事情我都干过,我也希望我的这些经验可以对你有所帮助。&br&&br&首先是一本好的C++书籍(Accelerated C++, C++ Primer),然后以及尽量多的完成书籍的习题,可以帮助完成C++语法的学习。虽然前面的书籍涵盖了标准库,但是不够完善,这个时候你可以选择在线查阅C++标准库这种泛型的学习方式,也可以选择阅读《C++标准库》的方式进行学习。通过这样的步骤,你应该可以完成C++的初步学习了。&br&&br&然后,由于C++是一门系统级语言,我想你需要到大三学习操作系统的时候,才会明白栈与堆、内存管理等更深层次的含义。但是,在明白这些概念之前不会妨碍你利用C++做一些事情,比如写一个简单的XML Parser。这个时候,你应该会发现很多问题,如效率,代码规范等,这个时候,你可以研究Effective C++,Google C++ Code Standard等,只有自己犯了错,回过头反省才会更加深刻。&br&&br&随后,你可以更加深刻的去思考C++,你需要阅读《The Design and Evolution of C++》。这本书的阅读,会教会你很多,是对你影响最大的C++书籍。如果你对C++编译器的一些细节有兴趣,深入C++对象模型可以推荐。如果你对STL的一些实现有兴趣,可以去翻翻STL源代码(很多人推荐STL源码剖析,但是我没有阅读过,我没有办法发表是否应该推荐的观点,列出来供你自行判断是否应该阅读)。&br&&br&到这一步骤,我想你应该可以称为C++ Programmer了,剩下的就是实践中发现问题,然后补足自己。&br&&br&此外,由于C++博大精深,应用的范围多如牛毛,特定方向所需要的知识未列举。比如你要研究Android的NDK什么的,那就是属于你后面的事情了。&br&&br&===================Update============================================&br&说实话,我也不知道这一条为什么突然火了,发现突然有很多的赞。其实正如第一句而言,这是我走过来的经验,我不能说这就是权威的(甚至不能说是正确的),而当初回答这个问题也是以我走过来的经验来回答一个初学者的困惑。而这位初学者的困惑在我大一的时候也出现过,所以一下就引起了我的共鸣,我也只想把我的经验说出来希望可以帮助提问者少走一些弯路而已。至于这样学习的C++够不够,我想我按照这样的路线学习,可以做到我有能力去IBM写C++编译器,那么我想对于就单纯题主所提的C++语言方面来说应该已经足够了。诚然,计算机的世界不仅计算机编程语言,与之相关的还有操作系统、数据结构、编译原理、计算机网络等知识,但是,我想我们可以再开另外一个问题。同时,既然别人问了如何学C++,你让别人学Java、Python等,或者说C++大坑的,我觉得这种回答其实挺不好的,因为别人问什么,你老实认真答什么就好了,何必把自己的意愿加在别人的身上呢。
由于我大一也陷入过迷茫,也走过一些弯路,那时候学不会直接记忆代码之类的事情我都干过,我也希望我的这些经验可以对你有所帮助。 首先是一本好的C++书籍(Accelerated C++, C++ Primer),然后以及尽量多的完成书籍的习题,可以帮助完成C++语法的学习。…
《The Implementation of Functional Programming Language》,比什么私房菜要精彩、易懂和有用一百倍。&br&《Code》,这知识的程度只能是初中课外读物,虽然很多程序员都很吹捧,没看过的还是要看看。&br&《SICP》,大家都说好,虽然我没读过(因为知道这本书的时候已经太晚了,我翻了一下目录就知道不用看了),相比之下我认为&b&第一本加上《Haskell趣学指南》一起看&/b&获得的东西不仅涵盖SICP,还要更多。&br&《算法导论》,适合智商比较高的人当作入门读物,特别是在等以后的前女友迟到的时候。&br&&br&《Parsing Techniques》,进阶读物,当你背诵完《算法导论》每一个算法/数据结构的伪代码、复杂度和使用的前提条件,但是却找不到东西可以练习,而且又喜欢装逼的话,可以看这本。这本书号称一条公式也没有(后来我发现他一行代码也没有,估计作者认为代码跟公式一样难懂),但是有很多图例,超级入门。把这里面的知识全部实现完,《算法导论》的每一个细节你也同时锻炼了。&b&此书由于(在我发现的时候)全球只卖出100+本,所以你不要指望有任何人会去翻译他。同时作者也已经开放pdf下载了,不算盗版。&/b&&br&&br&要成为一个好的程序员,虽然要懂得,但是不要太去在意,更不要把别人发明出来的一些“巧合”视为自己知识的重要部分:譬如说一些叫creat的命令,如何挽救滚坏的系统,或者iPhone的正确大小写等等。
《The Implementation of Functional Programming Language》,比什么私房菜要精彩、易懂和有用一百倍。 《Code》,这知识的程度只能是初中课外读物,虽然很多程序员都很吹捧,没看过的还是要看看。 《SICP》,大家都说好,虽然我没读过(因为知道这本书的…
来个简单粗暴版。&br&&br&&br&假设你去西班牙旅游,肚子饿了;但你不会当地语言——就好像程序员想让CPU做什么,但他并不会二进制指令一样。&br&&br&于是,你掏钱请来一名懂汉语的翻译,告诉他,你想要一份开封菜(KFC);他自然会把你的话翻译成西班牙语,帮你完成点餐大业——这名翻译官,我们就叫他“编译器”。&br&&br&&br&&br&你很聪明,不打算下次继续掏钱给翻译。所以你用手机把翻译点餐时的对话录了下来;于是你再想吃饭,就只需要拿出手机重放一下就搞定了——我们把这个叫“可执行程序”。&br&&br&&br&&br&然后,你去了埃塞俄比亚。当肚子饿时,你又摸出了手机。很遗憾,当地人也听不懂西班牙语——这就叫CPU指令不兼容。&br&&br&于是,你只好重新雇佣翻译,要求点一份开封菜。&br&然而,听到翻译官的转述,当地人还是一脸茫然。因为那里并没有开封菜馆——这就叫API不兼容,即操作系统B并不提供、或者至少不以相同的方式提供操作系统A提供的功能。&br&&br&你只好先打听下当地有什么菜,然后从中选择一个比较可以接受的,同样完成了填肚子大业——这就叫“移植”(即利用另一个操作系统上提供的、和原始系统不同的其他接口,以不同的思路完成类似任务)。&br&&br&&br&当然,你同样鸡贼的录下了翻译的话。但第二天,你发现手机坏了;于是你重新买了一个,掏出坏手机上的老式大号SD卡,在新手机的micro SD插槽上比划了半天,发现根本不可能塞进去——这就是ABI不兼容:虽然包括电气规范、文件格式等等等等全都一样,但就是尺寸不对;你只能干瞪眼。&br&&br&&br&&br&最后,你忍无可忍,咬咬牙雇了个通晓一百多种语言的高级翻译随行。&br&现在,随便你走到哪,都不愁说话没人懂了。就是……贵的令人心痛——这种做法就叫“解释执行”。&br&&br&&br&等你回国后,和好朋友小明说起这事,小明笑弯了腰,说你真是个土老帽。&br&原来,你去的那些地方,都不难遇到懂英语的。只要你提前把可能遇到的问题都翻译成英语,然后到当地找个懂英语的就行了——相当于把英语当作“中间语言”(java的字节码),而当地懂两句英语的就是java虚拟机(jvm):你只要找到“jvm”,多少掏俩钱,给他们看看写着英文的纸条,他们就会帮你把事办成。
来个简单粗暴版。 假设你去西班牙旅游,肚子饿了;但你不会当地语言——就好像程序员想让CPU做什么,但他并不会二进制指令一样。 于是,你掏钱请来一名懂汉语的翻译,告诉他,你想要一份开封菜(KFC);他自然会把你的话翻译成西班牙语,帮你完成点餐大业—…
&b&欢迎转载,请标明作者和出处。&/b&&br&&br&&br&&b&作者:@马超Terminal&/b&&br&&br&&br&我的 Phd 研究方向是分布式系统,我老板也是搞分布式系统出身,我们实验室在这方面的积累还算不错,所以借此问题谈谈自己的看法。首先需要说明的是,分布式系统是一个复杂且宽泛的研究领域,学习一两门在线课程,看一两本书可能都是不能完全覆盖其所有内容的。介于这篇文章是引导初学者入门,所以我个人觉得为初学者介绍一下当前分布式系统领域的全貌,也许比直接推荐论文和课程更有帮助。当初学者对这个领域建立起一个大的 Picture 之后,可以根据自己的兴趣,有选择性的深入不同领域进行进一步的学习。&br&&br&这篇文章主要试图回答以下两个个问题:&br&&br&1. 近些年分布式系统领域都在做些什么。&br&2. 为什么现在投入分布式系统的学习和研究是值得的。&br&&br&我会尽可能多的去介绍更 “实用” 的分布式系统知识。 &br&&br&什么是实用?例如:&br&&br&Paxos 是分布式系统里一个重要而且实用的技术。&br&Consistent Hash 也是分布式系统里一个重要而且实用的技术。&br&MapReduce, Spark 等等都是很实用的系统。&br&&br&什么不实用? 例如:&br&&br&Paxos 算法的数学证明。&i&(注意此处“不实用” 和 “不重要”的区别)&/i&&br&&br&当然,分布式系统实在是一个太宽泛的话题,本人才疏学浅,回答也仅仅可能侧重于我所关心的领域和方向,很多地方都不能面面俱到。所以在此只能抛砖引玉, 蜻蜓点水,欢迎大家提出宝贵意见,我也会及时对文章进行修改和补充。&br&&br&&br&&b&分布式系统近些年都在做些什么?&/b&&br&&br&分布式系统是一个古老而宽泛的话题,而近几年因为 “大数据” 概念的兴起,又焕发出了新的青春与活力。除此之外,分布式系统也是一门理论模型与工程技法并重的学科内容。相比于机器学习这样的研究方向,学习分布式系统的同学往往会感觉:“入门容易,深入难”。的确,学习分布式系统几乎不需要太多数学知识(相比于机器学习),这也是为什么会造成 “入门容易” 的错觉。然而一旦深入下去,往往需要我们去体会 system 研究的 “简洁” 与 “美”,正如楼上 李沐 的回答中说的那样,系统工作是 “艺术” 而不是 “科学” ,这一点我觉得是系统研究工作最难,同时也是最精华的地方。总之把握一点原则:好的系统研究工作,尤其是分布式系统研究,一定是尽可能地用最简单、最直观的方法去解决实际的问题(看看 MapReduce 就知道了),因为简单就意味着实用。&br&&br&总的来说,分布式系统要做的任务就是把多台机器有机的组合、连接起来,让其协同完成一件任务,可以是计算任务,也可以是存储任务。如果一定要给近些年的分布式系统研究做一个分类的话,我个人认为大概可以包括三大部分:&br&&br&1. &b&分布式存储系统 &/b&&br&2. &b&分布式计算系统 &/b&&br&3. &b&分布式管理系统&/b&&br&&br&近十年来在这三个方向上,毫无疑问, Google 都是开创者,甚至很多业内人士都说,这十年是外界追随谷歌技术的十年。我们之前说到,分布式系统的研究是一门由实际问题驱动的研究,而 google 则是最先需要面对这些实际问题的公司。下面我们分别看看这三个方面工业界以及学术界这几年都在做些什么。&br&&br&&b&分布式存储系统:&/b&&br&&br&分布式存储系统是一个非常古老的话题,同时也是分布式系统里最难,最复杂,涉及面最广的问题。 往细了分,分布式存储系统大概可以分为四个子方向:&br&&br&&b&1. 结构化存储 &/b&&br&&b&2. 非结构化存储 &/b&&br&&b&3. 半结构化存储 &/b&&br&&b&4. In-memory 存储&/b&&br&&br&除了这四个子方向之外,分布式存储系统还有一系列的理论、算法、技术作为支撑:例如 &i&Paxos&/i&, &i&CAP&/i&, &i&Consistent&/i&&i&Hash&/i&, &i&Timing (时钟)&/i&,
&i&2PC, 3PC&/i& 等等,这些内容我们会在后面提到。现在,我们先来看看上述四个子方向大致都在干些什么。&br&&br&&b&结构化存储(structured storage systems)&/b&的历史非常古老,典型的场景就是事务处理系统或者关系型数据库(RDBMS)。传统的结构化存储都是从单机做起的,比如大家耳熟能详的
MySQL。有句话说:MySQL的成长史就是互联网的成长史。这一点也不为过。除了 MySQL 之外,PostgreSQL 也是近几年来势头非常强劲的一个 RDBMS.
我们发现,传统的结构化存储系统强调的是:(1)结构化的数据(例如关系表)。(2)强一致性 (例如,银行系统,电商系统等场景)(3)随机访问(索引,增删查改,SQL 语言)。然而,正是由于这些性质和限制,结构化存储系统的可扩展性通常都不是很好,这在一定程度上限制了结构化存储在大数据环境下的表现。随着摩尔定律面临的瓶颈,传统的单机关系型数据库系统面临着巨大的挑战。不过真的没办法了吗?在此我们先埋下一个伏笔:)&br&&br&&b&非结构化存储 (no-structed storage systems). &/b&和结构化存储不同的是,非结构化存储强调的是高可扩展性,典型的系统就是分布式文件系统。分布式文件系统也是一个古老的研究话题,比如 70 年代的 Xerox Alto, 80 年代的 NFS, AFS, 90 年代 xFS 等等。然而,这些早期的分布式文件系统只是起到了网络磁盘的作用, 其最大的问题就是不支持 容错 (fault tolerance)和 错误恢复 (fault recovery)。而 Google 在 2003 年 SOSP 上推出的 GFS (google file system) 则是做出了里程碑的一步,其开源实现对应为
GFS 的主要思想包括:&br&&br&(1)用 master 来管理 metadata。&br&(2)文件使用 64MB 的 chunks 来存储,并且在不同的 server 上保存多个副本。&br&(3)自动容错,自动错误恢复。&br&&br&Google 设计 gfs 最初的目的是为了存储海量的日志文件以及网页等文本信息,并且对其进行批量处理(例如配合 mapreduce 为文档建立倒排索引,计算网页 PageRank 等)。和结构化存储系统相比,虽然分布式文件系统的可扩展性,吞吐率都非常好,但是几乎无法支持随机访问(random access)操作,通常只能进行文件进行追加(append)操作。而这样的限制使得非结构化存储系统很难面对那些低延时,实时性较强的应用。&br&&br&&b&半结构化存储 (semi-structure storage systems)&/b&的提出便是为了解决结非构化存储系统随机访问性能差的问题。我们通常会听到一些流行的名词,比如 NoSQL, Key-Value Store,
甚至包括对象存储,例如 protobuf,thrift 等等。这些都属于半结构化存储研究的领域,其中以 NoSQL 近几年的发展势头尤为强劲。NoSQL 系统既有分布式文件系统所具有的可扩展性,又有结构化存储系统的随机访问能力 (例如随机update, read 操作),系统在设计时通常选择简单键值(K-V)进行存储,抛弃了传统 RDBMS 里复杂 SQL 查询以及 ACID 事务。这样做可以换取系统最大的限度的可扩展性和灵活性。在 NoSQL 里比较有名系统包括:Google 的 Bigtable, Amazon 的 Dynamo, 以及开源界大名鼎鼎的 HBase,Cassandra 等.
通常这些 NoSQL 系统底层都是基于比较成熟的存储引擎,比如 Bigtable 就是基于 LevelDB ( jeff dean 写的,非常好的 C++ 源码教程) ,底层数据结构采用 LSM-Tree. 除了 LSM-Tree 之外 B-Tree (B+Tree)也是很成熟的存储引擎数据结构。&br&&br&&b&In-memory 存储。&/b&随着业务的并发越来越高,存储系统对低延迟的要求也越来越高。 同时由于摩尔定律以及内存的价格不断下降,基于内存的存储系统也开始普及。 In-memory 存储顾名思义就是将数据存储在内存中, 从而获得读写的高性能。比较有名的系统包括 memcahed ,以及 Redis。 这些基于 K-V 键值系统的主要目的是为基于磁盘的存储系统做 cache。还有一些偏向于内存计算的系统,比如可以追溯到普林斯顿 Kai Lee 教授早期的研究工作 distributed shared memory ( DSM ),斯坦福的 RamCloud, 以及最近比较火的基于 lineage 技术的 tachyon (Alluxio) 项目(Spark生态系统子项目)等等。&br&&br&&b&NewSQL.
&/b&我们在介绍结构化存储时说到,单机 RDBMS 系统在可扩展性上面临着巨大的挑战,然而 NoSQL 不能很好的支持关系模型。那是不是有一种系统能兼备 RDBMS 的特性(例如:完整的 SQL 支持,ACID 事务支持),又能像 NoSQL 系统那样具有强大的可扩展能力呢? 2012 年 Google 在 OSDI 上发表的 Spanner,以及 2013 年在 SIGMOD 发表的 F1, 让业界第一次看到了关系模型和 NoSQL 在超大规模数据中心上融合的可能性。不过由于这些系统都太过于黑科技了,没有大公司支持应该是做不出来的。比如 Spanner 里用了原子钟这样的黑科技来解决时钟同步问题,打破光速传输的限制。在这里只能对 google 表示膜拜。&br&&br&我们在之前提到,分布式存储系统有一系列的理论、算法、技术作为支撑:例如 &i&Paxos&/i&, &i&CAP&/i&, &i&Consistent &/i&&i&Hash&/i&, &i&Timing (时钟)&/i&, &i&2PC, 3PC&/i& 等等。那么如何掌握好这些技术呢?以我个人的经验,掌握这些内容一定要理解其对应的上下文。什么意思呢?就是一定要去思考为什么在当下环境需要某项技术,如果没有这个技术用其它技术替代是否可行,而不是一味的陷入大量的细节之中。例如:如何掌握好 Paxos?
Paxos本质上来说是一个三阶段提交,更 high level 讲是一个分布式锁。理解paxos必须一步一步从最简单的场景出发,比如从最简单的 master-backup 出发,发现不行,衍生出多数派读写,发现还是不行,再到 paxos.
之后再了解其变种,比如 fast paxos, multi-paxos. 同理为什么需要 Consistent Hash, 我们可以先思考如果用简单range partition 划分数据有什么问题。再比如学习 2pc, 3pc 这样的技术时,可以想想他们和paxos 有什么关系,能否替代 paxos。&br&&br&以上是我关于分布式存储系统内容的一些总结,推荐一些相关的论文 ,有兴趣的读者可以看看:&br&&br&&a href=&//link.zhihu.com/?target=https%3A//www.baidu.com/link%3Furl%3DSS7YNMslkAEuO1E8bDqjsHO4VCAkEiInpDkTiD6B8AAdmjr2vFkOUpEk9mAR5FWcEBkvzeBcXoLnAQgAx0QWzh2_aEW_VDLucUhH7NdrA1clT8kO3AJ6rNbx2jf0g9yS%26wd%3D%26eqid%3D8e651dda44d9& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The Google File System&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//lintool.github.io/UMD-courses/bigdata-2015-Spring/content/ChangFay_etal_OSDI2006.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Bigtable: A Distributed Storage System for Structured Data.&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dynamo: Amazon's Highly Available Key-value ... &i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//lintool.github.io/UMD-courses/bigdata-2015-Spring/content/Khurana_etal_2012.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Introduction to HBase Schema Design&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//lintool.github.io/UMD-courses/bigdata-2015-Spring/content/Abadi_2012.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Consistency Tradeoffs in Modern Distributed Database System Design&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.usenix.org/conference/osdi12/technical-sessions/presentation/corbett& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Spanner: Google’s Globally-Distributed Database&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.google.com.hk/url%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D3%26ved%3D0ahUKEwiZ1Lb5xLvPAhUH3mMKHSlOBlwQFggzMAI%26url%3D%74%2f%252f%74%63%6e%61%6e%252e%256f%2f%74%2f%66%6c%66%65%46%32%25%44%74%62%65%32%51%254c%30%74%61%25%54%74%30%61%256c%2e%66%26usg%3DAFQjCNGfWnwIaiTelNwV1WvQkKTVdQxARA& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&F1: A Distributed SQL Database That Scales&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.google.com.hk/url%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D11%26ved%3D0ahUKEwirlq61xbvPAhUG9WMKHTaBC9AQFghJMAo%26url%3D%74%2f%252f%77%252e%2e%72%256b%65%65%2f%257e%6f%61%256e%252f%70%73%252f%31%73%256f%5f%63%6f%256e%252e%66%26usg%3DAFQjCNE7YQV3FT8kx6lE9uq342_qcdpoBA& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Tachyon: Reliable, Memory Speed Storage for Cluster Computing&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.google.com.hk/url%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D9%26ved%3D0ahUKEwjCv53exbvPAhVX7mMKHYU7ByIQFghkMAg%26url%3D%74%2f%252f%77%252e%69%6f%2f%74%2f%66%6c%66%65%4a%256f%4f%74%68%256f%5f%4d%6f%2e%66%26usg%3DAFQjCNEM-UPY2o8QlRy4QcQlfBFqFLTBeg& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&RAMCloud and the Low- Latency Datacenter&i class=&icon-external&&&/i&&/a&&a href=&//link.zhihu.com/?target=https%3A//www.cs.cornell.edu/projects/ladis2009/papers/lakshman-ladis2009.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Cassandra - A Decentralized Structured Storage System&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//homes.cs.washington.edu/%7Ebillhowe/mapreduce_a_major_step_backwards.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&MapReduce: A major step backwards&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//lintool.github.io/UMD-courses/bigdata-2015-Spring/content/Stonebraker_etal_CACM2010.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&MapReduce and Parallel DBMSs: Friends or Foes?&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//www.baidu.com/link%3Furl%3DgpEJK81Kna-aic8i5y8_b0hGhItJiGfBrBPymDKYh-QCCuWXAzMKRlTWn9x9niwIbgDRagOlNpArC-QiTNzMDv6L47Vq7YrO4dLQMEbsXK0pqNI-r2L6p-4Bb70k_Tw7& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&A comparison of approaches to large scale data analysis&i class=&icon-external&&&/i&&/a&&br&&br&&br&&b&分布式计算系统&/b&&br&&br&聊完了分布式存储系统,让我们来聊聊分布式计算系统 :) 首先解决一个很多初学分布式计算的同学的疑惑:分布式计算和并行计算是一回事吗?最初我也有这样的疑惑,而现在我的理解是这样的:&br&&br&传统的并行计算要的是:投入更多机器,数据大小不变,计算速度更快。&br&分布式计算要求:投入更多的机器,能处理更大的数据。&br&&br&换句话说二者的出发点从一开始就不同,一个强调 high performance, 一个强调 scalability. 举例来说,MapReduce 给业界带来的真正的思考是什么?其实是给我们普及了 google 这样级别的公司对真正意义上的「大数据」的理解。因为在 04 年论文出来之前,搞并行计算的人压根连 「容错」的概念都没有。换句话说,分布式计算最为核心的部分就是「容错」,没有容错,分布式计算根本无从谈起。MapReduce 统要做成这个样子(map + reduce),其实就是为了容错。&br&&br&然而很多初学分布式计算的同学对容错的概念多多少少是有误解的。包括我在初学 mapreduce 的时候也会思考:好好的计算怎么就会出错了呢?一方面,由于硬件的老化,有可能会导致某台存储设备没有启动起来,某台机器的网卡坏了,甚至于计算运行过程中断电了,这些都是有可能的。然而最平凡发生的错误是计算进程被杀掉。因为 google 的运行环境是共有集群,任何一个权限更高的进程都可能 kill 掉你的计算进程。设想在一个拥有几千台机器的集群中运行,一个进程都不被 kill 掉的概率几乎为零。具体的容错机制我们会在后面介绍具体的系统时提到。&br&&br&另一个有意思的话题是,随着机器学习技术的兴起,越来越多的分布式计算系统是为了机器学习这样的应用设计的,这也是我比较关注的研究领域,也会在后面重点谈到。&br&&br&如同分布式存储系统一样,我对分布式计算系统也做了一个分类,如下:&br&&br&&b&1. 传统基于msg的系统 &/b&&br&&b&2. MapReduce-like 系统 &/b&&br&&b&3. 图计算系统&/b&&br&&b&4. 基于状态(state)的系统 &/b&&br&&b&5. Streaming 系统&/b&&br&&br&当然不同的人可能会有不同的分类方法,不过大同小异。我们接下来聊聊这些系统都在干些什么。&br&&br&&b&传统基于msg的系统 . &/b&这类系统里比较有代表性的就是 MPI (message passing interface). 目前比较流行的两个 MPI 实现是 mpich2 和 openmpi . MPI 这个框架非常灵活,对程序的结构几乎没有太多约束,以至于大家有时把 MPI 称为一组接口 API, 而不是系统框架。在这些 API 里最常用的两个就是 send 和 recv 接口(还有一系列非阻塞扩展接口,例如:Isend, Irecv 等)。MPI 除了提供消息传递接口之外,其框架还实现了资源管理和分配,以及调度的功能。除此之外,MPI 在高性能计算里也被广泛使用,通常可以和 Infiniband 这样的高速网络无缝结合。&br&&br&除了 send 和 recv 接口之外,MPI 中另一个接口也值得注意,那就是 AllReduce. 这个接口在很多机器学习系统开发里都很用。因为很多并行机器学习系统都是各个进程分别训练模型,然后再合适的时候(例如一轮迭代结束)大家同步一下答案,达成共识,然后继续迭代。这个 “达成共识” 的操作往往可以很方便的通过 AllReduce 来完成。 AllReduce 接口具有两个优点:1. 高效。 2. 实用简单。 先说说为什么使用简单。使用 AllReduce 通常只需要在单机核心源码里加入
AllReduce 一行代码,就能完成并行化的功能。说 AllReduce 高效的原因是因为其底层消息传递使用了 tree aggregation,尽可能的将计算分摊到每一个节点。&br&&br&可是,既然 AllReduce 这么好,为什么在实际大大规模计算中很少看到呢?原因很简单,就是因为
MPI 不支持容错,所以很难扩展到大规模集群之上。不过最近陈天奇写了一个支持容错的 allreduce 接口,叫rabit,有兴趣的同学可以关注一下。 大名鼎鼎的 xgboost 底层的分布式接口就是 rabit.&br&&br&&b&MapReduce-like 系统.
&/b&这一类系统又叫作 dataflow 系统,其中以 MapReduce (Hadoop) 和 Spark 为代表。其实在学术界很有很多类似的系统例如 Dryad, FlumeJava, Twister 等等。这一类系统的特点是将计算抽象成为 high-level operator, 例如像 map,reduce,filter 这样的函数式算子,然后将算子组合成 DAG ,然后由后端的调度引擎进行并行化调度。其中,MapReduce 系统属于比较简单的 DAG,只有 map 和 reduce 两层节点。MapReduce 这样的系统之所以可以扩展到超大规模的集群上运行,就是因为其完备的容错机制。在 Hadoop 社区还有很多基于 mapreduce 框架的衍生产品,比如 Hive (并行数据库OLAP), Pig(交互式数据操作)等等。&br&&br&MapReduce-like 的编程风格和 MPI 截然相反。MapReduce对程序的结构有严格的约束——计算过程必须能在两个函数中描述:map 和 reduce;输入和输出数据都必须是一个一个的 records;任务之间不能通信,整个计算过程中唯一的通信机会是 map phase 和 reduce phase 之间的 shuffuling phase,这是在框架控制下的,而不是应用代码控制的。因为有了严格的控制,系统框架在任何时候出错都可以从上一个状态恢复。Spark 的 RDD 则是利用 Lineage,可以让数据在内存中完成转换。&br&&br&由于良好的扩展性,许多人都机器学习算法的并行化任务放在了这些平台之上。比较有名的库包括 Mahout (基于Hadoop), 以及 MLI (基于 Spark) .
然而这些系统最大缺点有两点:&br&&br&1. 这些系统所能支持的机器学习模型通常都不是很大。导致这个问题的主要原因是这系统在 push back 机器学习模型时都是粗粒度的把整个模型进行回传,导致了网络通信的瓶颈。有些机器学习的模型可以大到无法想象,比如我们用 Field-aware factorization machine (FFM)做
criteo 的 ctr prediction 时模型大小可以达到100 GB.&br&&br&2. 严格的 BSP 同步计算使得集群的效率变的很低。也就是说系统很容易受到straggle的影响。&br&&br&&b&图计算系统. &/b&图计算系统是分布式计算里另一个分支,这些系统都是把计算过程抽象成图,然后在不同节点分布式执行,例如 PageRank 这样的任务,很适合用图计算系统来表示。最早成名的图计算系统当属 Google
的 pregel,该系统采用 BSP 模型,计算以 vectex 为中心。随后又有一系列图计算框架推出,例如:GPS (对 Pregel 做了优化,除了vectex-centric computation,还有 global computation,动态调整分区等等。)Giraph / Hama 都是基于 Hadoop 的 Apache 的开源 BSP 图计算项目。&br&&br&除了同步(BSP)图计算系统之外,异步图计算系统里的佼佼者当属 GraphLab,该系统提出了 GAS 的编程模型。目前这个项目已经该名为 dato.,专门推广基于图的大规模机器学习系统。&br&&br&&b&基于状态(state)的系统. &/b&这一类系统主要包括 2010 年 OSDI 上推出的 Piccolo, 以及后来 2012 年 nips 上 Google 推出的 distbelief,再到后来被机器系学习领域广泛应用的 Parameter Server 架构。这里我们重点介绍一下 Parameter Server 这个架构。&br&&br&我们之前说,MPI 由于不支持容错所以很难扩展至大规模集群之中;MapReduce 系统无法支持大模型机器学习应用,并且节点同步效率较低。用图抽象来做机器学习任务,很多问题都不能很好的求解,比如深度学习中的多层结构。而 Parameter Server 这种 state-centric 模型则把机器学习的模型存储参数上升为主要组件,并且采用异步机制提升处理能力。参数服务器的概念最早来自于 Alex Smola 于 2010 年提出的并行
LDA 架构。它通过采用分布式的 memcached 作为存放参数的存储,这样就提供了有效的机制作用于不同worker节点同步模型参数。 Google 的 jeff dean 在 2012 年进一步提出了第一代 Google Brain 大规模神经网络的解决方案 Distbelief. 在后来的
的 Eric xing 以及百度少帅 李沐 都提出了更通用的 Parameter server 架构。&br&&br&如果要深入 Parameter server 系统的设计,需要一些机器学习的背景,比如什么是 ssp
协议, 在此我们就不详细讨论了。&br&&br&&b&Streaming 系统. &/b&Streaming 系统听名字就能看出来是为流式数据提供服务的。其中比较有名的系统包括 Storm, Spark Streaming, Flink 等等。由于本人对这个领域并不是很熟,就不详细介绍了。&br&&br&&br&以上是我对分布式计算系统的一些介绍,其实每一个方向深入下去都是一个研究领域,在此推荐一些论文:&br&&br&&a href=&//link.zhihu.com/?target=https%3A//www.google.com.hk/url%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D1%26ved%3D0ahUKEwimgKrZgb7PAhVS_mMKHZv2AEsQFgggMAA%26url%3D%74%2f%252f%73%72%2e%6f%65%252e%6d%252f%63%76%6d%72%75%2d%256f%69%2e%66%26usg%3DAFQjCNEL7nTxrQ6fiMUtt4AZh6gK5og2IQ& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&MapReduce: Simplified Data Processing on Large Clusters&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.google.com.hk/url%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D1%26ved%3D0ahUKEwjurZjsgb7PAhUM62MKHavWDhoQFggaMAA%26url%3D%74%2f%252f%77%252d%66%252e%63%252e%75%252f%257e%256d%6c%79%74%63%63%69%39%252d%6c%256c%2f%70%73%252f%256e%69%255f%61%2e%66%26usg%3DAFQjCNFzpytpG78Bbg8BIWalnQK6FF3UOA& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Resilient Distributed Datasets&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.cs.cmu.edu/%7Emuli/file/parameter_server_osdi14.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Scaling Distributed Machine Learning with the Parameter Server&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//vldb.org/pvldb/vol5/p716_yuchenglow_vldb2012.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Distributed GraphLab: A Framework for Machine Learning&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.usenix.org/event/osdi10/tech/full_papers/Power.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Piccolo: Building Fast, Distributed Programs with Partitioned ..&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.cs.cmu.edu/%7E./seunghak/petuum_kdd15.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Petuum: A New Platform for Distributed Machine Learning on Big Data&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.google.com.hk/url%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D1%26ved%3D0ahUKEwjdp5uagr7PAhVY92MKHVgeDx0QFggdMAA%26url%3D%74%3a%252f%252f%61%256e%72%65%2f%257e%7a%2f%61%63%256c%73%252f%69%73%252f%5f%72%6d%67%252e%66%26usg%3DAFQjCNFCSnjtM2UnnYZyuO8h0nBBKo6vfQ& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Spark Streaming&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//www.microsoft.com/en-us/research/publication/dryad-distributed-data-parallel-programs-from-sequential-building-blocks/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dryad: Distributed Data-parallel Programs from Sequential Building ...&i class=&icon-external&&&/i&&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//papers.nips.cc/paper/4687-large-scale-distributed-deep-networks.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Large Scale Distributed Deep Networks - NIPS Proceedings&i class=&icon-external&&&/i&&/a&&br&&br&&b&分布式管理系统:&/b&&br&&br&(未完待续)
欢迎转载,请标明作者和出处。 作者:@马超Terminal 我的 Phd 研究方向是分布式系统,我老板也是搞分布式系统出身,我们实验室在这方面的积累还算不错,所以借此问题谈谈自己的看法。首先需要说明的是,分布式系统是一个复杂且宽泛的研究领域,学习一两门在…
要不要黑一下 C++呢?呵呵呵。&br&------------------&br&咱们要有点娱乐精神,关于 C++的笑话数都数不清:&br&&br&笑话:C++是一门不吉祥的语言,据说波音公司之前用ADA为飞机硬件编程,一直用的好好的,后来招聘了一伙大学生,学生们说我靠还在用这么落后的语言,然后换成C++重构后飞机就坠毁了。&br&&br&笑话:什么是C++程序员呢?就是本来10行写得完的程序,他非要用30行来完成,并自称“封装”,但每每到第二个项目的时候却将80%打破重写,并美其名曰 “重构”。&br&&br&笑话:C容易擦枪走火打到自己的脚,用C++虽然不容易,但一旦走火,就会把你整条腿给炸飞了。&br&&br&笑话:同时学习两年 Java的程序员在一起讨论的是面向对象和设计模式,而同时学习两年 C++的程序员,在一起讨论的是 template和各种语言规范到底怎么回事情。&br&&br&笑话:教别人学 C++的人都挣大钱了,而很多真正用 C++的人,都死的很惨。&br&&br&笑话:C++有太多地方可以让一个人表现自己“很聪明”,所以使用C++越久的人,约觉得自己“很聪明”结果步入陷阱都不知道,掉坑里了还觉得估计是自己没学好 C++。&br&&br&笑话:好多写了十多年 C++程序的人,至今说不清楚 C++到底有多少规范,至今仍然时不时的落入某些坑中。&br&&br&笑话:很多认为 C++方便跨平台的人,实际编写跨平台代码时,都会发现自己难找到两个支持相同标准的 C++编译器。&br&---------------&br&&br&Q:那 C++为什么还能看到那么多粉丝呢?&br&A:其实是因为 Windows,因为 Windows的兴起带动了 C++,C++本来就是一门只适合开发 GUI的语言。&br&&br&Q:为何 C++只适合开发 GUI呢?&br&A:你看 Unix下没有 GUI,为啥清一色的 C呀?所有的系统级问题都能在 C里找到成熟的解决方案,应用级问题都能用其他高级语言很好地解决,哪里有 C++什么事情呀?&br&&br&Q:你强词夺理,Unix下也有 C++的项目呀。&br&A:有,没错,你任然可以用任何语言编写任何糟糕的代码。&br&&br&Q:别瞎扯了,你都在说些什么?连C++和 Windows 都扯到一起去了。&br&A:回想下当年的情景,一个大牛在教一群初学者如何编程。一边开发一边指着屏幕上说,你看,这是一个 Button,我们可以用一个对象来描述它,那是一个 panel我们也可以用一个对象来描述它,并且你们有没有发现,其实 Button和 Panel是有血缘关系的,你们看。。。这样就出来了。。。。下面的学生以前都是学着学校落后的教材,有些甚至还在用 turboc的 bgi库来画一些点和圆。哪里见过这么这么华丽的 Windows 界面呀。大牛说的话,象金科玉律一样的铭刻在自己幼小的心理。一边学着 Windows,一边发现,果然,他们都需要一个基类,果然,他们是兄弟关系,共同包含一些基本属性,可以放到基类去。他们越用越爽,潜意识里觉得因为 C++这么顺利的帮他们解决那么多界面问题,那看来 C++可以帮他们解决一切问题了。于是开发完界面以后,他们继续开发,当他们碰到各种设计问题时,反而认为肯定自己没有用好 C++。于是强迫自己用下去,然后就完蛋了。&br&&br&---------------&br&关于 C++的笑话我有一箩筐,各位 C++粉用不着对号入座。言归正传,为什么要黑 C++呢?谈不上黑不黑,我从94年开始使用 C++(先前是 C 和 Pascal),一路看着 C++成长壮大,用 C++写过的代码,加起来应该超过 10MB了吧,C++的各种宝典我也都读过,一直到 2004年开始切回 C,主要原因是发现很多没法用 C++思路继续解决下去的问题,或者说用
C++思路解决下去会很糟糕的问题。&br&&br&那时候()正是 C++满天飞的时候,言必称 C++,用必用模版,我跳出来说你们醒醒吧,别过火了,这个世界并不是都是抽象数据结构和算法就可以描述清楚的。于是很多人激动的跳出来说:“你没领会到 C++精髓,你根本都不会用 C++”。我问他们:“语言是用来解决问题的,如果一个语言学了三四年都会经常掉沟里,算好语言么?如果编写十多年 C++的程序员都很难掌握得了,这算好语言么”。他们又说:“语言是死的,人是活的”。&br&&br&我记得当时一位国内 C++大牛,为了纠正我的 “错误观点”,给我看过他写的一套十分强大的库,我打开一看,倒吸了一口冷气,全部是 .h文件。我只能回他三个字:“你牛逼”。当然这是一个极端的例子,那家伙后来终于也开始把 .h里面的东西逐步挪到
.cpp里面了,这是好事。&br&&br&当时和云风在一家公司,2004年新人培训时,他给新人布置了一个实现内存分配器的作业,批改作业的时候,他经常边看边问人家,“不够C++呀,你能不能百分之百OOP?”,“1%的 C都不要留”。我当时在公司内部邮件列表里面发过关于 C++的问题,大部分人都表示:“你看没有C++我们怎么写3D引擎呢?”。我跟他们讲:“John Carmack直到 Quake3都还在用着 ANSI C,后来因为不得不支持 D3D,改用 C++了。为啥 C不能写 3D引擎了?”。他们告诉我:“你看,Point,就是个对象,Matrix也是个对象,那么多 Vector的代数计算,用 C++的算术重载是多么美妙的事情,三维世界就是对象的世界。”。&br&&br&确实当时客户端 GUI的话,只有 C++,图形引擎也只有 C++,这两个正是C++最强的地方,所以我也没和他们争辩,强迫他们承认 C也可以很漂亮的写图形,而且C写的可以写的很优雅。我又不是闲着没事情,何必去质疑人家的核心价值观呢,呵呵。当年我正在接手一个 C++项目,代码超过 800KB,每次崩溃都需要花费很长时间去定位,项目中大量的前后依赖,改一个地方,前后要看好几处,一处遗漏,整个系统就傻逼了。我开始重构后,画了两个星期,将性能敏感的核心部分剥离出来用 C实现(代码量仅 200KB),然后导出 Python接口,用Python来完成剩下的部分,整个脚本层代码量只有 150KB。整个世界清爽了,整个 C++项目原来的工期为 2个程序员四个月,我一个人重构的时间加起来就 1.5个月,而且代码量比远来少了两倍还多,各种奇特的 BUG也一扫而尽。我看看左边的 800KB一团乱麻的 C++代码,再看看右边整洁的 300多 KB 纯 C + Python,琢磨着,这个项目干嘛不一开始就这么做?&br&&br&&b&跨语言接口&/b&&br&&br&现代项目开发,不但需要更高的性能,而且需要更强大的语言描述能力。而 C++正处在一个尴尬的地方,比底层,它不如 C能够精确的控制内存和硬件,各种隐式构造让你防不胜防;比描述能力,比快速业务开发和错误定位,它又赶不上 Python, Ruby, Lua等动态语言,处于东线和西线同时遭受挤压和蚕食的地步。&br&&br&很快,&a href=&tel:& class=&&&&/a&年左右,其他项目组各种滥用 C++的问题开始显现出来:当时脚本化已经在工程实践中获得极大的成功,然而某些项目一方面又要追求 100%的 C++,另一方面又需要对脚本导出接口,他们发现问题了,不知道该怎么把大量的 C++基础库和接口导给 Lua。&br&&br&C的接口有各种方便的方式导给脚本,然而整个项目由一群从来就不消于使用脚本的cpp大牛开发出来,当他们要吧cpp类导出接口给脚本时,他们设计了一套牛逼的系统,lua自动生成机器码,去调用c++的各种类,没错,就是c++版本的cffi或者ctypes。他为调用vc的类写了一套机器码生产,又为调用gcc的类写了一套代码生成。那位cpp大牛写完后四处炫耀他的成果,后来他离职了,项目上线一而再再而三的出现无可查证的问题,后}

我要回帖

更多关于 webp 浏览器兼容 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信