差不多的wwWwww39pppp.cnom23是什么,刚刚浏览的www39pppp.cnom23cOm怎么不显示了

国外有一篇非常好的Node.js 介绍文章,从原理入手讲解,在这里给大家翻译一下(本人非翻译出身,一些地方结合了点个人理解,有错误欢迎指出)。&br&&br&原文地址 &a href=&//link.zhihu.com/?target=http%3A//www.sitepoint.com/node-js-is-the-new-black/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Node.js is the New Black&/a&&br&&br&&br&&b&译文如下:&/b&&br&如果你去年注意过技术方面的新闻,我敢说你至少看到node.js不下一两次。那么问题来了“node.js是什么?”。有些人没准会告诉你“这是一种通过JavaScript语言开发web服务端的东西”。如果这种晦涩解释还没把你搞晕,你没准会接着问:“为什么我们要用node.js?”,别人一般会告诉你:node.js有非阻塞,事件驱动I/O等特性,从而让高并发(high concurrency)在的轮询(Polling)和comet构建的应用中成为可能。&br&&br&&p&当你看完这些解释觉得跟看天书一样的时候,你估计也懒得继续问了。不过没事。我这篇文章就是在避开高端术语的同时,帮助你你理解node.js的。&/p&&br&&p&浏览器给网站发请求的过程一直没怎么变过。当浏览器给网站发了请求。服务器收到了请求,然后开始搜寻被请求的资源。如果有需要,服务器还会查询一下数据库,最后把响应结果传回浏览器。不过,在传统的web服务器中(比如Apache),每一个请求都会让服务器创建一个新的进程来处理这个请求。&/p&&br&&p&后来有了Ajax。有了Ajax,我们就不用每次都请求一个完整的新页面了,取而代之的是,每次只请求需要的部分页面信息就可以了。这显然是一个进步。但是比如你要建一个FriendFeed这样的社交网站(类似人人网那样的刷朋友新鲜事的网站),你的好友会随时的推送新的状态,然后你的新鲜事会实时自动刷新。要达成这个需求,我们需要让用户一直与服务器保持一个有效连接。目前最简单的实现方法,就是让用户和服务器之间保持长轮询(long polling)。&/p&&br&&p&HTTP请求不是持续的连接,你请求一次,服务器响应一次,然后就完了。长轮训是一种利用HTTP模拟持续连接的技巧。具体来说,只要页面载入了,不管你需不需要服务器给你响应信息,你都会给服务器发一个Ajax请求。这个请求不同于一般的Ajax请求,服务器不会直接给你返回信息,而是它要等着,直到服务器觉得该给你发信息了,它才会响应。比如,你的好友发了一条新鲜事,服务器就会把这个新鲜事当做响应发给你的浏览器,然后你的浏览器就刷新页面了。浏览器收到响应刷新完之后,再发送一条新的请求给服务器,这个请求依然不会立即被响应。于是就开始重复以上步骤。利用这个方法,可以让浏览器始终保持等待响应的状态。虽然以上过程依然只有非持续的Http参与,但是我们模拟出了一个看似持续的连接状态&/p&&br&&p&我们再看传统的服务器(比如Apache)。每次一个新用户连到你的网站上,你的服务器就得开一个连接。每个连接都需要占一个进程,这些进程大部分时间都是闲着的(比如等着你好友发新鲜事,等好友发完才给用户响应信息。或者等着数据库返回查询结果什么的)。虽然这些进程闲着,但是照样占用内存。这意味着,如果用户连接数的增长到一定规模,你服务器没准就要耗光内存直接瘫了。&/p&&br&&p&这种情况怎么解决?解决方法就是刚才上边说的:&b&非阻塞&/b&和&b&事件驱动&/b&。这些概念在我们谈的这个情景里面其实没那么难理解。你把非阻塞的服务器想象成一个loop循环,这个loop会一直跑下去。一个新请求来了,这个loop就接了这个请求,把这个请求传给其他的进程(比如传给一个搞数据库查询的进程),然后响应一个回调(callback)。完事了这loop就接着跑,接其他的请求。这样下来。服务器就不会像之前那样傻等着数据库返回结果了。&/p&&br&&p&如果数据库把结果返回来了,loop就把结果传回用户的浏览器,接着继续跑。在这种方式下,你的服务器的进程就不会闲着等着。从而在理论上说,同一时刻的数据库查询数量,以及用户的请求数量就没有限制了。服务器只在用户那边有事件发生的时候才响应,这就是&b&事件驱动。&/b&&/p&&br&&p&FriendFeed是用基于Python的&b&非阻塞&/b&框架Tornado (知乎也用了这个框架) 来实现上面说的新鲜事功能的。不过,Node.js就比前者更妙了。Node.js的应用是通过javascript开发的,然后直接在Google的变态V8引擎上跑。用了Node.js,你就不用担心用户端的请求会在服务器里跑了一段能够造成阻塞的代码了。因为javascript本身就是事件驱动的脚本语言。你回想一下,在给前端写javascript的时候,更多时候你都是在搞事件处理和回调函数。javascript本身就是给事件处理量身定制的语言。&/p&&br&&p&Node.js还是处于初期阶段。如果你想开发一个基于Node.js的应用,你应该会需要写一些很底层代码。但是下一代浏览器很快就要采用WebSocket技术了,从而长轮询也会消失。在Web开发里,Node.js这种类型的技术只会变得越来越重要。&/p&&br&&p&以上。&/p&
国外有一篇非常好的Node.js 介绍文章,从原理入手讲解,在这里给大家翻译一下(本人非翻译出身,一些地方结合了点个人理解,有错误欢迎指出)。 原文地址
译文如下: 如果你去年注意过技术方面的新闻,我敢说你至少看到node.js不…
(嗯..简单说明一下,下面只是当初写一个node小项目用到的东西,自己随手总结了一下,学完这些,大概能从前端到后端自己随手写一些node的小东西,但想要深入学习node,下面是远远不够的,别的回答里有一些推荐的深入学习的,推荐看一看~)&br&-----------------------------------------------------------------------------------------------------&br&Node:&br&1.《nodejs入门》,才38页,很好,书中项目做一下,学会基础&br&&p&2.《nodejs开发指南》。180多页,很好,书中项目做一下,知道基础,及基本的配合express,jquery,bootstrap,数据库MongoDB&/p&&p& 另附一些node实现书中例子的一些变化&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/meteoric_cry/archive//2604890.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用Express3.0实现&Node.js开发指南&/a&&br&&/p&&p&3.开始看express创建初始项目的源代码对比2中的书,发现express更新后新的特性:&a href=&//link.zhihu.com/?target=https%3A//github.com/strongloop/express/wiki/Migrating%2520from%25203.x%2520to%25204.x& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Migrating from 3.x to 4.x · strongloop/express Wiki · GitHub&/a&&/p&&p&看express官网api&/p&&p&英文:&a href=&//link.zhihu.com/?target=http%3A//expressjs.com/api.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Express 4.x - API Reference&/a&&/p&&p&中文:&a href=&//link.zhihu.com/?target=http%3A//expressjs.jser.us/api& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Express - api参考&/a&&/p&&p&4.之后发现,一个系列课程,从零开始nodejs系列文章:&a href=&//link.zhihu.com/?target=http%3A//blog.fens.me/series-nodejs/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&从零开始nodejs系列文章&/a&&/p&&p&其中 文章: Node.js开发框架Express4.x:&a href=&//link.zhihu.com/?target=http%3A//blog.fens.me/nodejs-express4/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Node.js开发框架Express4.x&/a& ,详细介绍了express4项目的基本内容,很好&/p&&p&
文章:用Nodejs连接MySQL:&a href=&//link.zhihu.com/?target=http%3A//blog.fens.me/nodejs-mysql-intro/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&用Nodejs连接MySQL&/a&,介绍mysql与node基本,及数据库连接池,宕机,连接超时等node问题解决办法,node-mysql官网也有相应英文解决办法&/p&&p&5.node+json:&a href=&//link.zhihu.com/?target=https%3A//cnodejs.org/topic/4f81bd2b7c8f& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&node.js里面怎么创建和解析JSON格式的文件?&/a&&/p&&p&更全的是这一个&a href=&//link.zhihu.com/?target=http%3A//stackoverflow.com/questions/5726729/how-to-parse-json-using-node-js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&How to parse JSON using Node.js?&/a& 但要注意如果require json,只加载一次,更新之后,再使用,可能还是老版本&/p&&p&json不好查看的问题:&a href=&//link.zhihu.com/?target=https%3A//github.com/zhanhongtao/blog/issues/73& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&读写 JSON 文件
· Issue #73 · zhanhongtao/blog · GitHub&/a&&/p&&p&6.node邮件验证:&a href=&//link.zhihu.com/?target=http%3A//blog.fens.me/nodejs-email-nodemailer/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Nodejs发邮件组件Nodemailer&/a&&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//blog.csdn.net/chszs/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&选择适合的Node.js授权认证策略&/a&&br&&/p&&p&7.很全的node module &a href=&//link.zhihu.com/?target=https%3A//github.com/joyent/node/wiki/Modules%23parsers-json& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Modules · joyent/node Wiki · GitHub&/a&&/p&&p&8.文件操作,要么官方文档:&a href=&//link.zhihu.com/?target=https%3A//nodejs.org/api/fs.html%23fs_fs_writefile_filename_data_options_callback& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&File System Node.js v0.12.2 Manual & Documentation&/a&,&/p&&p&或者&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/chyingp/p/node-guide-file-write.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&node基础-文件系统&/a&&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/rubylouvre/archive//2264717.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&node.js 文件操作&/a&,有一个要注意的是 存储文件时,比如writefile写路径 要使用path.join(__dirname, “相对于当前文件路径”); 如path.join(__dirname, &../upload/recordList/& + generateID(&record&) + &.json&);,后端要采用这种dirname的形式,前端可以直接写相对于当前文件路径的形式&/p&&br&node+express&br&1.整体介绍框架&a href=&//link.zhihu.com/?target=http%3A//javascript.ruanyifeng.com/nodejs/express.html%23toc5& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Express框架 -- JavaScript 标准参考教程(alpha)&/a&&br&2.express取值:&a href=&//link.zhihu.com/?target=https%3A//cnodejs.org/topic/50a333d7637ffa4155c62ddb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用 NodeJS + Express 從 GET/POST Request 取值&/a&&br&3.session+cookie:&a href=&//link.zhihu.com/?target=http%3A//www.tuicool.com/articles/INbmuy& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&node.js web开发:EXPRESS 4.x 以上使用session和cookie 的记录&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/chenchenluo/p/4197181.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&express 框架之session&/a&
express-session官网 &a href=&//link.zhihu.com/?target=https%3A//www.npmjs.com/package/express-session& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&npmjs.com 的页面&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//my.oschina.net/braveqin/blog/208556& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Node.js Express 从入门到菜鸟(二)——Cookie+Session+三层搭建&/a&&br&&a href=&//link.zhihu.com/?target=http%3A//my.oschina.net/u/1466553/blog/294336& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&express 4.2.0 使用session和cookies&/a&&br&&a href=&//link.zhihu.com/?target=https%3A//cnodejs.org/topic/dda& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&在Express 使用session 做登录控制&/a&&br&去掉flash之后,可以只用session,在每次post一开始 置req.session.error为null,之后,验证过程中,检查错误再设置req.session.error,然后根据结果redirect之后,检测是否error为null,来决定是否展示&br&node session保存的只是中间键值对,不管赋予res.locals.user等,都不是对象,需要在中间件中重新生成对象,才能调用方法,当然如果只是使用属性值,则不需要&br&4.express基本的中间件官方网站:&a href=&//link.zhihu.com/?target=https%3A//github.com/senchalabs/connect%23middleware& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&senchalabs/connect · GitHub&/a&&br&&br&&br&&p&node+mysql&/p&&p&1.node所用的mysql官网:&a href=&//link.zhihu.com/?target=https%3A//github.com/felixge/node-mysql& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&felixge/node-mysql · GitHub&/a&&/p&&p&2.&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/zhongweiv/p/nodejs_mysql.html%23mysql_curd& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Nodejs学习笔记(四)--- 与MySQL交互(felixge/node-mysql)&/a&&/p&&p&3.&a href=&//link.zhihu.com/?target=http%3A//blog.fens.me/nodejs-mysql-intro/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&用Nodejs连接MySQL&/a&&/p&&p&4.&a href=&//link.zhihu.com/?target=http%3A//blog.csdn.net/justdb/article/details/8200512& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&三种常用数据库(Oracle、MySQL、SQLServer)的分页之MySQL分页&/a&&/p&&p&5.sq语句注意顺序,order by group by limit..一般放在where后面&/p&&br&&p&express+ejs&/p&&p&1.&a href=&//link.zhihu.com/?target=http%3A//my.oschina.net/u/1540325/blog/311901& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&EJS学习总结 -
双月通天的个人空间&/a&&/p&&p&2.&a href=&//link.zhihu.com/?target=http%3A//blog.csdn.net/zhangxin09/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&EJS 模板快速入门&/a&&/p&&p&3.&a href=&//link.zhihu.com/?target=http%3A//node-js.diandian.com/post//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nodejs express template (模版)的使用 (ejs + express)_node.js 笔记&/a&&/p&&p&4.ejs我的总结:&/p&&p& ejs 写法:&/p&&div class=&highlight&&&pre&&code class=&language-text&&普通传入并使用变量:&%= title %&
普通for执行js代码(for中间的代码一定可以执行到):
&% for(var i=0; i&headerNavbar. i++) {%&
&li&&a href=&/reg&&&%= headerNavbar[i].name %&&/a&&/li&
特殊if语句的js代码(if中间的额代码不一定可以执行到):
&% if(active=='index'){%&
class=&active&
&/code&&/pre&&/div&&br&&p&jquery&/p&&p&1.&a href=&//link.zhihu.com/?target=http%3A//www.w3school.com.cn/jquery/index.asp& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jQuery 教程&/a&&/p&&p&2.&a href=&//link.zhihu.com/?target=http%3A//javascript.ruanyifeng.com/jquery/utility.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jQuery工具方法 -- JavaScript 标准参考教程(alpha)&/a&&/p&&p&3.&a href=&//link.zhihu.com/?target=http%3A//tool.oschina.net/apidocs/apidoc%3Fapi%3Djquery& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&在线文档-jquery&/a&&/p&&p&4.&a href=&//link.zhihu.com/?target=http%3A//www.ruanyifeng.com/blog/2011/07/jquery_fundamentals.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jQuery设计思想&/a&!!&/p&&br&&p&jquery ui&/p&&p&1.&a href=&//link.zhihu.com/?target=https%3A//jqueryui.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jQuery UI&/a&&/p&&p&2.中文API:&a href=&//link.zhihu.com/?target=http%3A//www.css88.com/jquery-ui-api/resizable/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&http://www.css88.com/jquery-ui-api/&/a&&/p&&p&3.&a href=&//link.zhihu.com/?target=http%3A//www.w3cschool.cc/jqueryui/example-resizable.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jQuery UI 实例&/a&&/p&&p&4.jqueryrain神站:tabs:&a href=&//link.zhihu.com/?target=http%3A//www.jqueryrain.com/example/jquery-tabs/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&80+ Best jQuery Tabs with Examples&/a&&/p&&p&
js tree 库:&a href=&//link.zhihu.com/?target=http%3A//www.jqueryrain.com/demo/jquery-treeview/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&15+ jQuery Treeview Plugin & jQuery Tree with Example&/a&&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//www.jstree.com/api/%23/%3Ff%3D%2524.jstree.defaults.core.expand_selected_onload& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jsTree&/a&&/p&&br&&p&Bootstrap:&/p&&p&1.&a href=&//link.zhihu.com/?target=http%3A//v2.bootcss.com/base-css.html%23typography& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&基本CSS样式 · Bootstrap&/a& v2&br&&/p&&p&2.&a href=&//link.zhihu.com/?target=http%3A//v3.bootcss.com/css/%23type& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&全局 CSS 样式 · Bootstrap 中文文档&/a& v3&/p&&p&3.bootstrap row等偏移-20px&/p&&p&4.&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/niuox/p/3583650.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&补充:学会Twitter Bootstrap不再难&/a& :从2.x升级到3.0版本&/p&&br&&p&html5 &/p&&p&1.drag:库:&a href=&//link.zhihu.com/?target=http%3A//interactjs.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&interact.js - JavaScript drag and drop, resizing and gestures with inertia and snapping&/a&&a href=&//link.zhihu.com/?target=http%3A//skidding.github.io/dragdealer/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dragdealer.js&/a&
教程:&a href=&//link.zhihu.com/?target=http%3A//w3school.com.cn/html5/html_5_draganddrop.asp& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HTML 5 拖放&/a&&a href=&//link.zhihu.com/?target=http%3A//www.zhangxinxu.com/wordpress/2011/02/html5-drag-drop-%25E6%258B%%258B%25BD%25E4%25B8%258E%25E6%258B%%2594%25BE%25E7%25AE%%25BB%258B/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HTML5 drag & drop 拖拽与拖放简介 <<
张鑫旭&/a&&/p&&br&&p&git:&/p&&p&1.&a href=&//link.zhihu.com/?target=http%3A//blog.csdn.net/iefreer/article/details/7679631& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Git:代码冲突常见解决方法&/a&&/p&&p&2.&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/by1990/archive//2916860.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用WebStorm和Git开发Node.js应用&/a&&/p&&p&3.&a href=&//link.zhihu.com/?target=http%3A//riny.net/2014/git-ssh-key/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&git生成ssh key及本地解决多个ssh key的问题&/a& 写的非常清楚&/p&&p&4.&a href=&//link.zhihu.com/?target=https%3A//help.github.com/articles/generating-ssh-keys/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Generating SSH keys&/a&&/p&&br&&p&js:&/p&&p&1.对象本身方法,可以用于对这类对象的工具类方法,当作对象manager方法&/p&&p& 对象原型中方法,用于每个不同对象实例的方法&/p&&p&2.&a href=&//link.zhihu.com/?target=http%3A//www.ruanyifeng.com/blog/2012/12/asynchronous%25EF%25BC%25BFjavascript.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Javascript异步编程的4种方法&/a& callback尽量写成return callback()&/p&&p&3.&a href=&//link.zhihu.com/?target=http%3A//liaofeng-xiao.iteye.com/blog/697029& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JS对象类型的确定&/a&&/p&&p&4.js取属性,一般用object.pro ,如果需要动态确定属性,可以使用 object['dynamic'+pro],动态取属性,包括session,虽然为键值对,但这样也可以&/p&&br&&p&json:&/p&&p&1.jquery操作:&a href=&//link.zhihu.com/?target=http%3A//blog.csdn.net/abeetle/article/details/8910189& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jQuery中读取json文件&/a&&/p&&br&&p&后端更新前端:&/p&&p&1.&a href=&http://www.zhihu.com/question/& class=&internal&&怎么使用 JavaScript 将网站后台的数据变化实时更新到前端? - 前端开发&/a&&/p&&p&2.&a href=&//link.zhihu.com/?target=http%3A//blog.fens.me/nodejs-socketio-chat/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Socket.io在线聊天室&/a&&/p&&p&3.&a href=&//link.zhihu.com/?target=https%3A//cnodejs.org/topic/4f32142e69bab4d67601bd1b& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&迈出nodejs的第二步,用nodejs+socket.io搭建一个websocket聊天室&/a&&/p&&p&4.&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/zhaodongyu/p/3905500.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用Node.js实现数据推送&/a&&/p&&p&5.&a href=&//link.zhihu.com/?target=https%3A//github.com/Automattic/socket.io& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Automattic/socket.io · GitHub&/a&&/p&&p&6.&a href=&//link.zhihu.com/?target=http%3A//blog.fens.me/nodejs-websocket/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Nodejs实现websocket的4种方式&/a&&/p&&br&&p&RESTFul:&/p&&p&1.&a href=&//link.zhihu.com/?target=http%3A//pixelhandler.com/posts/develop-a-restful-api-using-nodejs-with-express-and-mongoose& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Pixelhandler's Blog&/a&&/p&&p&2.&a href=&//link.zhihu.com/?target=http%3A//www.ruanyifeng.com/blog/2011/09/restful.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&理解RESTful架构&/a&&/p&&br&&br&&p&杂:&/p&&p&1. passportJS配置用户验证:&a href=&//link.zhihu.com/?target=http%3A//blog.ssyog.com/blog/webbuild/passportjs-req-user-is-undefined.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PassportJS 配置失败:req.user 未定义&/a&&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//passportjs.org/guide/configure/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Passport
| Configure&/a&&br&&/p&&p&2.回调函数:回调函数,就是放在另外一个函数(如 parent)的参数列表中,作为参数传递给这个 parent,然后在 parent 函数体的某个位置执行。&a href=&//link.zhihu.com/?target=http%3A//www.jb51.net/article/54641.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&理解javascript中的回调函数(callback)_javascript技巧&/a&&/p&&p&3.不再用的req.flsah():&a href=&//link.zhihu.com/?target=https%3A//cnodejs.org/topic/502b7f61f767cc9a51525b4a& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&express 版本更新后遇到的问题
flash()&/a&&/p&&p&4.app.locals和res.locals &a href=&//link.zhihu.com/?target=http%3A//www.ituring.com.cn/article/55098& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&图灵社区 : 阅读 : express配置项more&/a&&/p&&p&5.Crypto加密解密:&a href=&//link.zhihu.com/?target=http%3A//blog.fens.me/nodejs-crypto/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Node.js加密算法库Crypto&/a&&/p&&p&6.&a href=&http://www.zhihu.com/question/& class=&internal&&在 CSS 中如何使用百分比设置页面 Div 高度? - 前端开发&/a&&/p&&p&7.&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/suzongwei/archive//1396337.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HTML:scrollLeft,scrollWidth,clientWidth,offsetWidth之完全详解(转载)&/a&&/p&&p&8.&a href=&//link.zhihu.com/?target=http%3A//www.ruanyifeng.com/blog/2012/08/file_upload.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&文件上传的渐进式增强&/a&&/p&&p&拖动上传 js库:&a href=&//link.zhihu.com/?target=http%3A//www.dropzonejs.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dropzone.js&/a&&/p&&p&9.js diagram 需求图:&a href=&//link.zhihu.com/?target=http%3A//www.jointjs.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JointJS - the HTML 5 JavaScript diagramming library.&/a&&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//gojs.net/latest/index.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&gojs.net/latest/index.h&/span&&span class=&invisible&&tml&/span&&span class=&ellipsis&&&/span&&/a&&br&&/p&&p&10js 网页分析:&a href=&//link.zhihu.com/?target=http%3A//www.google.com/analytics/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Google Analytics Official Website&/a&&/p&&p&11.js network网状图 ,时间线,2d,3d 库:&a href=&//link.zhihu.com/?target=http%3A//visjs.org/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&vis.js - A dynamic, browser based visualization library.&/a&&/p&&p&12.js fileManager:&a href=&//link.zhihu.com/?target=http%3A//www.sitepoint.com/10-jquery-file-manager-plugins/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&10 jQuery Based File Manager Plugins&/a&&/p&&p&
在线富文本编辑器:&a href=&//link.zhihu.com/?target=http%3A//www.responsivefilemanager.com/index.php& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&RESPONSIVE filemanager 9.9.2&/a&(php tinyMCE)&/p&&p&推荐:&a href=&//link.zhihu.com/?target=http%3A//imperavi.com/redactor/plugins/file-manager/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Redactor Plugins&/a&轻量且美观&/p&&p&13.小型:file explore:&a href=&//link.zhihu.com/?target=https%3A//github.com/Kloudless/file-explorer& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Kloudless/file-explorer · GitHub&/a&:可以实现从多处上传,选择文件&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//tutorialzine.com/2014/09/cute-file-browser-jquery-ajax-php/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Cute File Browser with jQuery and PHP&/a& 美观轻量但是需要jquery ajax php&/p&&p&14. js tree 库:&a href=&//link.zhihu.com/?target=http%3A//www.jqueryrain.com/demo/jquery-treeview/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&15+ jQuery Treeview Plugin & jQuery Tree with Example&/a&&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//www.jstree.com/api/%23/%3Ff%3D%2524.jstree.defaults.core.expand_selected_onload& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jsTree&/a&&br&&/p&&p&15.messageBox 通知框 js库:&a href=&//link.zhihu.com/?target=http%3A//bootboxjs.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Bootbox.js—alert, confirm and flexible modal dialogs for the Bootstrap framework&/a&&/p&&p&16.&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/yjzhu/p/3227912.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【css】清除浮动(clearfix 和 clear)的用法&/a&&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//www.w3cplus.com/css/elements-horizontally-center-with-css.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&六种实现元素水平居中&/a&&br&&/p&&p&17.button css库:&a href=&//link.zhihu.com/?target=http%3A//www.bootcss.com/p/buttons/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Buttons - 一个高度可定制的按钮(button) CSS 样式库。&/a&&/p&&p&18.&a href=&//link.zhihu.com/?target=http%3A//blog.csdn.net/maxracer/article/details/6103348& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Html 解决长串英文字母显示不能自动换行&/a&&/p&&p&19.非input元素使用focus等方法:&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/rubylouvre/archive//1726334.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&让元素获得焦点&/a&&/p&&p&20.text file等在表单中同时上传时,记得表单设enctype=&multipart/form-data&,否则可能拿不到数据,还有一个,ajax传输data,记得设置data-type为json,尤其jstree使用ajax传输节点&/p&&p&21.多文件,多图片上传预览,进度等,可以用webuploader,busboy等&/p&&p&22.busboy &a href=&//link.zhihu.com/?target=http%3A//www.duanzhihe.com/1178.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nodejs+busboy实现文件上传&/a&&a href=&//link.zhihu.com/?target=https%3A//www.npmjs.com/package/busboy& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&npmjs.com/package/busbo&/span&&span class=&invisible&&y&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&23.前端字体:&a href=&//link.zhihu.com/?target=http%3A//www.youziku.com/Home/FontSelect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&字体选择_有字库&/a&&/p&&p&24.$('#btn').on('click',function(e){ e.preventDefaults(); })均能在表单提交之前阻止提交&/p&&p&24.404 not found 网页设计&a href=&//link.zhihu.com/?target=http%3A//www.ithome.com/html/it/28489.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&真没见识过,原来404错误页面可以这样设计&/a&&/p&&p&25.&a href=&//link.zhihu.com/?target=http%3A//www.html5rocks.com/zh/tutorials/file/dndfiles/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&阅读以 JavaScript 编写的本地文件&/a&&a href=&//link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/FileReader& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&FileReader - Web API 接口&/a& 读写客户端本地文件&/p&&p&26.chrome下 页面退出时发送ajax写法:&/p&&div class=&highlight&&&pre&&code class=&language-text&&$(window).on('beforeunload', function ()
//this will work only for Chrome
type:'GET',
url:'/ajaxRequest/myClassesOfteacherclose',
async:false
&/code&&/pre&&/div&27.前端中下面两个的$('a').text()是不一样的,会计算空格&div class=&highlight&&&pre&&code class=&language-text&&&a class='button'&关注&/a&
&a class='button'&
&/code&&/pre&&/div&&p&性能优化:&/p&&p&1.!!!&a href=&//link.zhihu.com/?target=http%3A//www.cnblogs.com/developersupport/p/webpage-performance-best-practices.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&毫秒必争,前端网页性能最佳实践&/a&&/p&&p&2.&a href=&//link.zhihu.com/?target=http%3A//www.w3school.com.cn/html5/html_5_app_cache.asp& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HTML 5 应用程序缓存&/a&&/p&&p&3.&a href=&//link.zhihu.com/?target=http%3A//www.appelsiini.net/projects/lazyload& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Lazy Load Plugin for jQuery&/a&&/p&&br&&p&持续更新~~&/p&
(嗯..简单说明一下,下面只是当初写一个node小项目用到的东西,自己随手总结了一下,学完这些,大概能从前端到后端自己随手写一些node的小东西,但想要深入学习node,下面是远远不够的,别的回答里有一些推荐的深入学习的,推荐看一看~) ------------------…
&p&归纳题主的问题:&/p&&p&这个世界上有各种各样的框架,设计这些五花八门框架的初衷到底是什么?我们该不该学习框架,该如何学习使用这些框架?&/p&&br&&p&回答题主的问题:&/p&&p&&b&一、首先,到底什么是框架?&/b&&/p&&p&想要回答这个问题,我们要慢慢来。&/p&&br&&p&&b&①&br&首先从DRY原则开始说起&/b&&/p&&p&Don't Repeat Yourself,不要重复你的代码。&/p&&p&DRY原则的重要性怎么提都不过分,很多人说编程是种机械性的工作,而有很多程序员也自嘲为码农,意为编程成了一种没有技术含量的体力性工作。如果不想沦为这个境界,首先需要的就是将DRY原则融入你的血液,在今后的编码工作中加以运用。&/p&&br&&p&1)最初级的DRY:语法级别&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&System.out.println(1);
System.out.println(2);
System.out.println(10);
&/code&&/pre&&/div&&p&我想只要学过基础语法,都会采用下面的形式。&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&for (int i = 1; i &= 10; i++) {
System.out.println(i);
&/code&&/pre&&/div&&p&如果发现有任何人采用上面一种形式的编码形式,那么不用怀疑,他对于编程绝对还没有入门。&/p&&p&我们当然会选择省力的做法,这种做法不但省力,还会有利于我们后续修改或扩展这组代码,如:&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&for (int i = 1; i &= 10; i++) {
System.out.println(i * 2 + 1);
&/code&&/pre&&/div&&p&我们进行这样的修改,只需要修改一处,而上面的形式却需要修改10处,当然会更麻烦且更容易出错,所以请记住能不重复就不重复。&/p&&br&&p&2)进阶的DRY原则:方法级别&/p&&p&当我们经常写一些重复性代码时,我们就要注意看能否将其抽取出来成为一个方法,如:&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
&/code&&/pre&&/div&&p&让我们将其抽取到一个方法 threadSleep() 中,这样我们只需要调用 threadSleep() 就可以实现原来的功能,不但所需敲击的代码更少,而且代码看起来更加清楚明白。而为了增加这个方法的复用性,我们还可以将其中固定的数字抽取成为参数,如:&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&private static void threadSleep(int millis) {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
&/code&&/pre&&/div&&p&这样我们就可以利用这个方法实现不同时间的sleep了。要注意提高代码的复用性也是实践DRY原则的一个重要方法,在后面我们也可以看到框架为了提高所谓的灵活性进行的一些设计,如在适当的位置增加扩展点。&/p&&br&&p&3)继续进阶的DRY原则:类型级别&/p&&p&现在我们看一个类&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&public class Person {
// Setter & Getter ...
&/code&&/pre&&/div&&p&我们新建一些Person类实例,并进行一些操作:&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&Person person = new Person();
person.setName(&jack&);
person.setAge(18);
Person person2 = new Person();
person2.setName(&rose&);
person2.setAge(17);
System.out.printf(&Name: %s, Age:%d\n&, person.getName(), person.getAge());
System.out.printf(&Name: %s, Age:%d\n&, person2.getName(), person2.getAge());
&/code&&/pre&&/div&&p&观察这些代码,其实有很大的DRY改造空间,首先可以添加一个构造方法&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&public Person(String name, int age) {
this.name =
this.age =
&/code&&/pre&&/div&&p&其次,可以添加一个toString()方法&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&public String toString() {
return String.format(&Name: %s, Age: %d&, name, age);
&/code&&/pre&&/div&&p&这样的话,上面的代码就可以改成下面的形式。&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&Person person = new Person(&jack&, 18);
Person person2 = new Person(&rose&, 17);
System.out.println(person.toString());
System.out.println(person2.toString());
&/code&&/pre&&/div&&br&&p&4)继续继续进阶的DRY原则:多个类组合级别&/p&&p&上面的代码我们其实还是有改善空间,就是利用容器类&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&List&Person& list = new ArrayList&&();
list.add(new Person(&jack&, 18));
list.add(new Person(&rose&, 17));
list.forEach(p -& System.out.println(p));
&/code&&/pre&&/div&&p&这里利用JDK8的Stream API以及Lambda表达式输出,其实可以进一步简化为 &/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&list.forEach(System.out::println);
&/code&&/pre&&/div&&p&这里我们可以看到,基本上我们写代码只写有变化的代码,而尽量不写机械性重复性的代码,其实后面我们就会知道,这就叫专注于业务逻辑,所谓业务逻辑就是你这个项目中,与别的项目都不一样的地方,必须由你亲自去编写实现的部分。&/p&&p&其实容器类很大程度上也是为了帮助我们编写代码而被设计出来的,首先让我们不必为每一个对象起名字(省去了person,person2,...等变量),然后又为批量操作提供了可能性。像是这样一系列有用的类组合起来可以称之为类库。常用的类库有Commons-Lang包等,为我们提供了一大批实用方法,我之所以提到类库,也是因为框架其实也是一种特殊的类库,但是却与一般的类库有着本质的不同。&/p&&br&&p&&b&②&br&设计模式,更高层级的DRY应用&/b&&/p&&p&上面我讲到了DRY原则的几个层次,一般情况下大家也早就这样使用了,属于入门之后很容易自己就想到得一些层次。但是设计模式不一样,设计模式是经过长时间编码之后,经过系统性的总结所提出的针对某一类问题的最佳解决方案,又称之为最佳实践。&/p&&p&而在小规模的编码工作中,其实并不需要什么设计模式,只有大型程序才有设计模式发挥的空间,所以我们需要借助一些特定领域有足够规模的问题来了解一下设计模式存在的必要性。&/p&&br&&p&1)连接数据库,进行一些操作,并安全释放数据库连接。&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&public static boolean updatePassword(String username, String password, String newpassword) {
Connection conn =
PreparedStatement stmt =
ResultSet rs =
boolean success =
conn = beginTransaction();
stmt = conn.prepareStatement(&select id, password from user where username = ?&);
stmt.setString(1, username);
rs = stmt.executeQuery();
if (rs.next()) {
if (rs.getString(&password&).equals(password)) {
PreparedStatement stmt2 =
stmt2 = conn.prepareStatement(&update user set password = ? where id = ?&);
stmt2.setString(1, newpassword);
stmt2.setLong(2, rs.getLong(&id&));
success = stmt2.executeUpdate() & 0;
} finally {
safeClose(stmt2);
commitTransaction(conn);
} catch (SQLException e) {
rollbackTransaction(conn);
throw new RuntimeException(e);
} finally {
safeClose(rs);
safeClose(stmt);
safeClose(conn);
&/code&&/pre&&/div&&p&上面是一个简单的数据库事务,虽然只有一个查询和一个更新,但是想要将其继续简化却并不容易,虽然其中有关于业务逻辑的部分只是少量几行代码,但是初始化,异常,提交,回滚操作让我们很难抽取出一个合适的方法来。虽然我们已经抽取出了 begin,commit,rollback,safeClose等方法,但是仍嫌繁琐。&/p&&p&我们发现之所以我们难以抽取方法,主要是因为流程,因为里面牵扯到流程控制,而流程控制一般是由我们程序员来控制的,所以也就必然需要我们手动编码来完成。难道真的就不能继续简化了吗?这就是需要设计模式的时候了。&/p&&br&&p&2)应用设计模式「模板方法模式」&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&public static boolean updatePassword(String username, String password, String newpassword) {
return connection(conn -& statement(conn, &select id, password from user where username = ?&, stmt -& {
stmt.setString(1, username);
return resultSet(stmt, rs -& {
if (rs.next()) {
if (rs.getString(&password&).equals(password)) {
long id = rs.getLong(&id&);
return statement(conn, &update user set password = ? where id = ?&, stmt2 -& {
stmt2.setString(1, newpassword);
stmt2.setLong(2, id);
return stmt2.executeUpdate() == 1;
&/code&&/pre&&/div&&p&可以看到,所有的conn,stmt,rs的开启和关闭,事务的提交和回滚都不用自己手动编写代码进行操作了,之所以可以达到这个效果,就是因为使用了模板方法设计模式,核心就是通过回调方法传递想对资源进行的操作,然后将控制权交给另一个方法,让这个方法掌握流程控制,然后适当的时候回调我们的代码(也就是我们自己写的业务逻辑相关的代码)。&/p&&p&这是需要额外写的几个方法&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&public interface ConnectionCallback&T& {
T doConnection(Connection conn) throws SQLE
public interface StatementCallback&T& {
T doStatement(PreparedStatement stmt) throws SQLE
public interface ResultSetCallback&T& {
T doResultSet(ResultSet rs) throws SQLE
public static &T& T connection(ConnectionCallback&T& callback) {
Connection conn =
T result =
conn = beginTransaction();
result = callback.doConnection(conn);
commitTransaction(conn);
} catch (SQLException e) {
rollbackTransaction(conn);
throw new RuntimeException(e);
} finally {
safeClose(conn);
public static &T& T statement(Connection conn, String sql, StatementCallback&T& callback) throws SQLException {
PreparedStatement stmt =
T result =
stmt = conn.prepareStatement(sql);
result = callback.doStatement(stmt);
} finally {
safeClose(stmt);
public static &T& T resultSet(PreparedStatement stmt, ResultSetCallback&T& callback) throws SQLException {
ResultSet rs =
T result =
rs = stmt.executeQuery();
result = callback.doResultSet(rs);
} finally {
safeClose(rs);
&/code&&/pre&&/div&&p&你们可能会疑惑,这些代码加上我们写的业务逻辑的代码,比原来的代码还要长,有什么必要使用这个设计模式。这正是我前面已经指出的一个问题,那就是要你的程序规模足够大才有必要应用设计模式,试想如果你有上百个乃至上千个数据库操作方法需要写,那么是不是写这几个额外的方法,就不算什么了呢。&/p&&p&其实这正是DRY原则在更高层次上的应用,即结合设计模式来达到更高层次的代码复用效果,进而应用DRY原则。而想要在这个层次继续向上攀升,那就必须是结合众多设计模式以及一些高层架构设计,能够帮助我们实现这一目的的就是框架。&/p&&br&&p&3)框架,是设计模式的集大成者,是DRY原则的最高应用&/p&&p&先让我们来看一下,使用框架会是什么样的一种体验?&/p&&p&这里以Hibernate + Spring声明式事务为例&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&@Transactional
public boolean updatePassword(String username, String password, String newpassword) {
User user = (User) session().createQuery(&from User where username = :username&)
.setString(&username&, username)
.uniqueResult();
if (user != null && user.getPassword().equals(password)) {
user.setPassword(newpassword);
&/code&&/pre&&/div&&p&可以发现令人惊讶的简洁,而且代码逻辑异常清晰,完全不需要考虑conn,stmt,rs等资源的释放,以及事务的提交和回滚,但是这些事情其实框架已经默默的帮我们做到了。这才叫真正的专注于业务逻辑,尽最大可能的只写与业务逻辑有关的代码。&/p&&p&当然这些框架的效果虽然神奇,其实只要细细探究其内部原理,是完全可以理解并掌握的。&/p&&br&&p&&b&二、那么问题就来了,框架到底是什么?要不要学,怎么学?&/b&&/p&&p&上面我说过了,框架其实就是一个或一组特殊的类库,特殊在什么地方?特殊在控制权转移!&/p&&p&框架与一般类库不同的地方是,我们调用类库,而框架调用我们。也就是说框架掌握整个程序的控制权,我们必须一定程度上把程序流程的控制权交给框架,这样框架才能更好的帮助我们。&/p&&p&下面以JavaWeb开发为例再进行一些说明,并顺便简单介绍一下JavaWeb的一些脉络。&/p&&br&&p&①&br&静态网页时代&/p&&p&本来网站都是一个个静态HTML组成的,或许这些网页还是用Dreamweaver写的,但是这样的静态页面显然不能满足我们,很快我们就迎来了动态网页的时代。&/p&&br&&p&②&br&Servlet时代&/p&&p&如果熟悉HTTP协议的话,我们就知道其实访问网页的过程不过是一次TCP连接罢了。浏览器发起TCP连接到服务器,服务器接受请求,然后返回HTML代码作为响应。那么我们完全可以等到接受到请求之后,再动态生成HTML代码返回给客户端。&/p&&p&Servlet就是这么做的,其主要代码不过是利用out.write()一点一点的输出HTML代码罢了。当然我们可以在其中掺杂一点动态的东西,如返回当前的时间。&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&out.write(&&!DOCTYPE html&\r\n&);
out.write(&&html&\r\n&);
out.write(&&head&\r\n&);
out.write(&&title&Index Page&/title&\r\n&);
out.write(&&/head&\r\n&);
out.write(&&body&\r\n&);
out.write(&Hello, & + new Date() + &\r\n&);
out.write(&&/body&\r\n&);
out.write(&&/html&\r\n&);
&/code&&/pre&&/div&&br&&p&③ JSP包打天下的时代&/p&&p&纯粹的Servlet很是丑陋,给前端程序员理解和修改这样的代码带来了很多困难。因此JSP技术被发明了出来,原理也不复杂,就是不直接写Servlet,而是先写好JSP文件,再由服务器将JSP文件编译成Servlet。而JSP中是以常见的HTML标签为主,这样前端程序员就能方便的修改这些代码了。&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&&!DOCTYPE html&
&title&Index Page&/title&
Hello, &%=new Date()%&
&/code&&/pre&&/div&&p&PS:由只使用 Servlet到使用JSP,虽然是一个简单的变化,但这迎合了前后端专业分工的大趋势,让前段人员只需要懂得HTML/CSS/JavaScrip代码就可以开始工作,而不需要学习Servlet那枯燥无味的用法,因此借着JSP技术的东风,JavaWeb技术迅速的扩展开来了。&/p&&br&&p&④ Servlet + JSP 时代&/p&&p&随着JSP技术的发展,用它写成的网站也越来越大,业务逻辑也越来越复杂。开发人员渐渐发现整个网站渐渐的再次变成了一团乱麻,不仅仅是JSP中夹杂了大量的Java代码,页面之间的耦合关系也越来越紧密。&/p&&p&即便是要修改一个简单的按钮文本,或者是引入一段静态的内容,也需要打开越来越庞大的JSP页面,艰难到找到需要修改的部分,有时还不仅仅是一处,这种修改是有很大的风险的,完全有可能引入新的错误。&/p&&p&这时候开发者渐渐意识到,仅仅使用JSP是不行的,JSP承担了太多的责任。这时人们又想起了Servlet,Servlet中主要使用Java代码,处理业务逻辑非常轻松。如果JSP只使用HTML代码,而将业务逻辑的代码转移到Servlet中,就可以大大的减轻JSP的负担,并且让前后端分工更加明确。&/p&&br&&p&⑤&br&MVC模式时代&/p&&p&在&br&Servlet + JSP模式的基础上,Java阵营进一步发展出了一种适合JavaWeb应用的设计模式,MVC设计模式,即将程序分为显示层(Viewer),控制层(Controller),模型层(Model)。如下图所示:&/p&&p&&figure&&img src=&https://pic4.zhimg.com/3cc75d6efa23b6269acb_b.png& data-rawwidth=&744& data-rawheight=&325& class=&origin_image zh-lightbox-thumb& width=&744& data-original=&https://pic4.zhimg.com/3cc75d6efa23b6269acb_r.png&&&/figure&一次典型的访问是这样的流程:&/p&&p&1. 用户输入网址或点击链接或提交表单,浏览器发起请求&/p&&p&2. --& 通过互联网,通过HTTP协议 --&&/p&&p&3. Tomcat接受到HTTP请求,生成HttpServletRequest对象,根据Web.xml的配置,调用开发者编写的HttpServlet,HttpServlet根据请求内容,调用JavaBean获取数据,JavaBean从数据库获取数据,返回HttpServlet,HttpServlet将数据转发给JSP,JSP负责将数据渲染为HTML,由Tomcat负责将HTML转化为HTTP响应,返回客户端。&/p&&p&4. --& 通过互联网,通过HTTP协议 --&&/p&&p&5. 客户端浏览器接收到HTTP响应,浏览器将HTML渲染为页面,并运行其中可能存在的JavaScript进一步调整界面。&/p&&br&&p&整个流程必须由开发者精确设计才能运作流畅,其中客户端HTML和JavaScript属于前端设计,服务器运行的其他内容属于后端设计。虽然符合J2EE规范的Tomcat等应用服务器已经帮我们实现了最复杂的一块,即HTTP协议部分,还给我们提供了JSP这个模板引擎,以及自定义标签等手段。但是在控制层,在模型层,J2EE能给我们的帮助少之甚少。&/p&&br&&p&就拿用户提交一个表单为例,而我们在Servlet中获取参数为例,虽然不用我们解析HTTP报文,应该已经是要谢天谢地了,但是我们要做的事情仍然很多,分析一下:&/p&&br&&p&1. 客户端传过来的数据全是文本,而我们需要的是Java对象。&/p&&p&2. 凡是文本就有编码问题,而这需要前后端配合解决。&/p&&p&3. 客户端的输入是不可信的,我们必须校验参数的合法性。&/p&&p&4. 我们还必须将校验结果反馈给客户,并且最好不要让客户全部重新输入。&/p&&p&5. 我们往往不是只有一个参数需要,而是有几个甚至更多参数,要妥善的处理各种情况组合。&br&&/p&&br&&p&这些事情几乎全部都需要我们手动编码来完成,几乎每一个 Servlet 都充斥着这样的代码,设置编码,获取参数,校验参数,校验通不过返回错误信息,校验通过则进行业务处理。而更重要的是,获取参数仅仅是整个流程中的一小步,我们的Servlet中存在着大量的重复性,机械性代码,而处理业务逻辑的代码可能只有一两行。&/p&&br&&p&⑥&br&JavaWeb框架&/p&&p&既然存在着大量的重复,我们当然不能忍,必须请出DRY大法。显然JavaWeb应用是一个规模庞大,流程复杂的应用,我们正需要JavaWeb框架的帮助。以Struts2框架为例,他能给我们什么帮助呢?&/p&&br&&p&1. 在控制层,由Struts2的核心控制器接管控制权,将本来在Web.xml进行配置的一些工作,转移到自定义的struts.xml文件中,这个文件的配置形式更友好。&/p&&p&2. Struts2封装了Serlvet Api,使用POJO对象作为控制器(Action),大量使用反射,不要求继承特定类,有利于复用及单元测试。提供ActionSupport类,结合struts2标签,能很方面实现的校验信息的收集及反馈。&br&&/p&&p&3. 提供国际化支持,在显示层有国际化相关的标签,在控制层由国际化相关的API。提供基于配置的校验及JS生成技术。智能化的参数类型转换,支持自定义转换器。提供Action拦截器,方便实现AOP模式。&/p&&p&4. 提供了基于OGNL表达式的数据共享模式,前后端数据交流更简单,提供了Struts2标签库,简单好用,支持多种模板,如FreeMarker,支持各种插件,如JSON,支持整合多种框架,如Spring。总之一句话,能在各方各面给我们强大的帮助。&/p&&br&&p&⑦&br&所以当然要学框架,要用框架,那么要怎么学?&/p&&p&1. 用框架要知其然,还要知其所以然,要大体明白框架实现一个功能特性的原理,不能只是会用,只是觉得很神奇就可以了。就拿前面的Hibernate + Spring声明式事务为例,要弄明白框架这部分是怎么实现的。&/p&&p&2. 首先要夯实你的语言基础,如JavaSE基础,语法掌握,用法掌握,有些同学语法还不熟练就开始学框架,等于地基没打就起高楼,你可能会快一步,但是迟早要遇到瓶颈,甚至摔跟头。&/p&&p&3. 那么何时开始学习框架?我不建议新手一开始就直接使用框架。&/p&&p&就好像一开始学习编程语言,大家都不推荐直接使用IDE,一定要用命令行自己编译运行几个文件之后,了解清楚了之后才可以使用IDE,要不然对于底层原理不了解,遇到问题没法自己手动排查。&/p&&p&4. 使用框架也是一样,如果不是自己写多了重复性的代码,就很难理解框架为什么要这么设计。如果不尝试几种不同的实现,就很难理解框架为了灵活性而做出的设计和扩展点。如果不写几十个权限检查语句,就很难理解AOP到底有什么好处。&/p&&p&5. 框架这么好,我该全部使用框架吗?首先只有在规模以上的程序中,才有应用框架的必要,一个简单的程序没必要使用框架,当然如果你很熟练,使用也无所谓。&/p&&p&6. 要学习一下框架的核心源代码,要为扩展框架做好准备,因为虽然框架基本上还算灵活,但是面对错综复杂的业务需求,永远不可能面面俱到,而你不了解框架的话,可能会给你实现业务需求造成麻烦。这也是有些人坚持使用Servlet+JSP原生开发,而不是用框架的理由。&/p&&p&7. 只要程序大了,归根究底还是要使用框架的,不是用别人写好的,就是自己写一套。这里我不建议自己写,不要重复造轮子,总有专业造轮子的。你草草写就的往往不如别人已经千锤百炼的代码。除非你是为了学习与研究的目的,自己写,那就是一件很好的事情。&/p&
归纳题主的问题:这个世界上有各种各样的框架,设计这些五花八门框架的初衷到底是什么?我们该不该学习框架,该如何学习使用这些框架? 回答题主的问题:一、首先,到底什么是框架?想要回答这个问题,我们要慢慢来。 ① 首先从DRY原则开始说起Don't Repeat…
&p& 叮咚,小伙伴们,我们又来啦。&/p&&p&还记得之前乐纯吃货天团立下的Flag么?——创造一款超好吃且吃不胖的逆天零食。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-179eacff917de8a2ab0f407_b.png& class=&content_image&&&/figure&&p&嗯,我们做出来了。&/p&&p&历时350天,召集了103位零食达人,吃掉了13斤零食后,我们终于把这个逆天零食研发出来了。&/p&&p&&b&它的名字叫「小补给」。&/b&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-3c906ee09ebb_b.png& class=&content_image&&&/figure&&p&食材和配方方面,我们从36种常见或不常见的坚果、谷物和果干中,选择了&b&粳米、黑麦、核桃仁、蔓越莓干、甜味椰片和南瓜籽仁。 &/b&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-333de0db20f674ea243d74a00a0897d8_b.png& class=&content_image&&&/figure&&p&加工方式方面,我们反复测试后,选用了&b&轻烘培·零油脂烘烤法&/b&,保持了坚果谷物自然的风味,也让整个零食包更好吃,更轻盈。&/p&&p&而这份逆天的健康零食,&b&每一包只有72kcal&/b&,这意味着你只需要一边吃着它一边看1小时电视,就能将它消耗完!&/p&&figure&&img src=&https://pic4.zhimg.com/v2-e6c6a6b024a5dcda6653f_b.png& class=&content_image&&&/figure&&p&作为一名吃货,我表示这将会是零食史上最适合在办公室里吃的神器!&/p&&p&以及,诚挚的邀请你来见证这个逆天的小奇迹。&/p&&p&详情可以咨询我们美美的首席吃货官艾琳噢,&b&艾琳的微信(ailin_bonnie)。记得发送搭讪信息:零食。&/b&&/p&&p&---------我是更新分割线----------&/p&&p&&b&我们花了整整15320元,才写出这篇文章。&/b& &b&看完之后,它能帮你:&/b& &b&1、省下至少12000元。&/b& &b&2、国内能买到的进口零食,最好吃又吃不胖的,几乎都在这里了。换句话说,以后下午、晚上肚子饿又怕胖,知道该吃什么好吃的了。
3、研发出市面上还不存在的超级吃不胖零食。&/b&&/p&&br&&p&&b&以下才是正文......&/b&&/p&&br&&p&p.s.文末有广告,慎入。&/p&&br&&p&------------------------------------&/p&&br&&p&这个丧心病狂的故事是这样开始的。&/p&&br&&p&乐纯一直在密谋研发一款超好吃、超百搭、吃不停、又吃不胖的逆天零食:它既可以搭配乐纯三三三倍的元气酸奶,也可以在饿肚子的时候随便抓几把吃。&/p&&br&&figure&&img src=&https://pic2.zhimg.com/18e41fb5ea5b894deefea31_b.png& class=&content_image&&&/figure&&p&&i&(超好吃又吃不胖的零食与滤乳清酸奶混合的美丽画面)&/i&&/p&&br&&p&&b&但是,子曰:要想做出逆天零食,一定要先吃遍世界。&/b&&/p&&br&&p&于是几周前,我们派出超级大吃货@艾琳,带上一麻袋的血汗钱,连续几天开始扫荡全北京的进口超市、某猫国际、某东国际、某码头、某红书,把所有能买得到的进口健康零食,都买回了乐纯实验室。&/p&&br&&figure&&img src=&https://pic4.zhimg.com/731caa3219fb6eaa1ef2bbc04e0b25c7_b.jpg& class=&content_image&&&/figure&&p&&i&(注重膳食平衡的乐纯超级大吃货@艾琳 的采购日常)&/i&&/p&&br&&p&最终,我们整整花了15320元大洋,&b&收集到了213种来自世界各地、但是可以在中国买到的吃吃吃不胖的零食&/b&(所有每百克热量都不到600大卡的嘎嘣脆谷物、坚果、果干)。远远不止是卡乐比啊——这应该是一个最完整版大合集了。&/p&&br&&figure&&img src=&https://pic4.zhimg.com/bb643dba3f6f17_b.jpg& class=&content_image&&&/figure&&br&&p&&b&然后,我们轮番地邀请了30万乐纯吃货粉丝中的60名资深健康吃货......&/b&&/p&&br&&p&有组织、有纪律、有预谋地,吃。吃。吃。吃。吃。&/p&&br&&p&一万五千多元的进口零食平铺在整整8米长的会议桌上,会有一种&b&「星球大战之吃货觉醒」&/b&的感觉。你感受一下(这还只是一部分噢):&/p&&br&&figure&&img src=&https://pic1.zhimg.com/aecb9882768_b.jpg& class=&content_image&&&/figure&&figure&&img src=&https://pic2.zhimg.com/f682c49a088bbfacf629_b.jpg& class=&content_image&&&/figure&&figure&&img src=&https://pic3.zhimg.com/c50c0eceae3c440b6bfe_b.jpg& class=&content_image&&&/figure&&br&&p&我们总结了一下,这213包吃不胖零食使用了以下36种吼吼吃的天然食材:&/p&&br&&figure&&img src=&https://pic2.zhimg.com/68d0fb2a62db98b48eb26d966fb1ffcd_b.jpg& class=&content_image&&&/figure&&br&&p&车轮战般丧心病狂地吃了三轮以后,我们汇集了60名吃货达人的数据反馈,得出了以下参考榜单,来指导我们一起研发终极吃不胖美味零食。接下来,就让我们先揭晓这份吃不胖榜单和它的评分标准......&/p&&br&&p&------------------------------------&/p&&ul&&li&&b&如何给吃不胖的零食打分?&/b&&/li&&/ul&&p&&b&- 上嘴指数&/b&&/p&&p&&b&乐纯的宗旨:再健康吃不胖的零食,不好吃都是耍流氓!&/b&一口咬下去,该酥脆的酥脆,该Q弹的Q弹,香甜而不粘牙,酸甜而不涩口,就一个字:爽。&/p&&br&&p&&b&- 吃不停指数&/b&&/p&&p&就是明明第一口没有那么惊艳,但停下来,那独特的味道在唇齿间游荡复又游荡,挠着你的心,让你重新打开它再吃一口。&/p&&br&&p&&b&- 吃不胖指数&/b&&/p&&p&一包零食,如果能有米其林三星般的美味,烫青菜般的热量,几乎没有吃货会拒绝。好吃不胖的零食才是好零食。&/p&&br&&p&&b&- 不上火指数&/b&&/p&&p&吃完零食后爆痘、嗓子疼是吃货们的心头大患。我们根据食材的寒、凉、温、热四性,和其加工过程中的火炙程度,来对零食搭配的上火指数做基本判断。&/p&&br&&br&&p&------------------------------------&/p&&ul&&li&&b&吃不胖零食榜单&/b&&/li&&/ul&&p&&u&在开始推荐之前,先揭晓一下213款里的极致差评款。&/u&&/p&&p&&u&你吃过土吗?这个比土还难吃。&/u&&/p&&br&&br&&p&&b&—— 吃吃吃香精 NO.1 ——&/b&&/p&&br&&figure&&img src=&https://pic3.zhimg.com/cbcdc130feda_b.jpg& class=&content_image&&&/figure&&p&&i&(Bakery on Main 燕麦、覆盆子干、蓝莓干、草莓干)&/i&&/p&&br&&p&在买吃的时候,看配料表是非常重要的工作。&/p&&p&但是——&b&你想知道在零食里香精加到极致是一种怎样的体验么?&/b&&/p&&p&买贝克欧曼吧。&/p&&p&&b&拆开袋子的那一瞬间,你就能闻到工业文明的味道。抓一把放到嘴里,谷物是软塌塌的,果干是酸甜到刺喉咙的。配上两口京霾,醉生梦死。&/b&&/p&&p&如果你是香精的狂热爱好者,尝尝吧。吃完以后,你会突然觉得生活中都一切都那样自然纯净,淳朴可爱。&/p&&br&&br&&p&&u&吐槽就到这了。&/u&&/p&&p&&u&接下来先推荐两款必须体验的「棒呆了」单品食材。&/u&&/p&&br&&br&&p&&b&——超清新果味 NO.1——&/b&&/p&&br&&figure&&img src=&https://pic1.zhimg.com/bf8a3abfc190_b.jpg& class=&content_image&&&/figure&&p&&i&(???? 雪梨干)&/i&&/p&&br&&p&&b&- 上嘴指数 ★★★★★★&/b&&/p&&p&&b&第一口就惊艳了。酥脆不粘牙,还没感慨完口感,雪梨的清甜就已经沿着味蕾骚动神经了,完美!&/b&&/p&&br&&p&&b&- 吃不停回味指数 ★★★★★★&/b&&/p&&p&&b&无论吃多少片都不觉得甜腻,加上完美的上嘴指数,怎么可能不吃吃吃不停。&/b&&/p&&br&&p&&b&- 吃不胖指数 ★★★★★★&/b&&/p&&p&300大卡/100克。今天推荐的热量倒数第一的健康零食,感受下。&/p&&br&&p&&b&- 不上火指数 ★★★★★&/b&&/p&&p&雪梨,性寒。上火了一般都喝冰糖炖雪梨呢。&/p&&br&&br&&p&&b&—— 超自然的味道 NO.1 ——&/b&&/p&&br&&figure&&img src=&https://pic4.zhimg.com/8fb388f35df9bfccd47f57_b.jpg& class=&content_image&&&/figure&&p&&i&(Market Grocer 蓝莓干)&/i&&/p&&br&&p&&b&- 上嘴指数 ★★★★&/b&&/p&&p&&b&非常与众不同的蓝莓干。扔几颗到嘴里,蓝莓的味道超!野!性!&/b&翻面一看配料表里果然写着野生蓝莓干。果肉里的小籽丰富了口感,让蓝莓的香气大大提升,略有些粘牙的小毛病可以忽略不计了。&/p&&br&&p&&b&- 吃不停指数 ★★★★★&/b&&/p&&p&入口的味道恰到好处,不多一丝酸不少一点甜,后味清新不失野性,就想一颗接着一颗嚼下去。&/p&&br&&p&&b&- 吃不胖指数 ★★★★★★&/b&&/p&&p&同样的300大卡/100克。你值得拥有。&/p&&br&&p&&b&- 不上火指数 ★★★★★&/b&&/p&&p&&b&蓝莓,性凉。放心大胆地吃。&/b&&/p&&br&&br&&p&&u&推荐完这两个单品,&/u&&/p&&p&&u&以下就是我们为你从213种吃不胖零食里,&/u&&/p&&p&&u&精选出来的各种最佳组合,从此不只有卡乐比。&/u&&/p&&br&&br&&p&&b&—— 超上嘴指数 NO.1 ——&/b&&/p&&br&&figure&&img src=&https://pic2.zhimg.com/a3f06e9fa51d89e49996b8dadc04554d_b.jpg& class=&content_image&&&/figure&&p&&i&(FAMILIA Crunch'X 燕麦、小麦、脆麦片、葡萄干、椰子片、烤榛子)&/i&&/p&&br&&p&&b&- 上嘴指数 ★★★★★&/b&&/p&&p&&b&一口咬下去就……停不下来了。谷物酥脆,一些葡萄干嵌在谷物上,黏黏地却不很粘牙,强烈推荐。&/b&&/p&&br&&p&&b&- 吃不停指数 ★★★★&/b&&/p&&p&谷物和烤榛子的香气完全融洽,后味有浓郁的椰子香,加上清新的葡萄干,回味无穷。&/p&&p&同时因为谷物含量比较多,而且调味加了些盐,吃不停的同时完全不腻。赞赞哒。&/p&&br&&p&&b&- 吃不胖指数 ★★★&/b&&/p&&p&464大卡/100克。比起动辄500、600大卡的零食包来说,算是表现不错的。&/p&&br&&p&&b&- 不上火指数 ★★&/b&&/p&&p&除了一丁丁的椰子能帮忙降低一下这个组合的热气,榛子是烤的,还有烘脆的麦片……吃多了会嗓子会有点儿干噢。&/p&&br&&br&&p&&b&—— 超回味指数 NO.1 ——&/b&&/p&&br&&figure&&img src=&https://pic3.zhimg.com/b7d6fe6e5a9fffceb701d59a_b.jpg& class=&content_image&&&/figure&&p&&i&(天六 杏仁、小鱼干、芝麻)&/i&&/p&&br&&p&&b&- 上嘴指数 ★★★★★&/b&&/p&&p&小鱼干啊小鱼干。这才是海洋的味道,我知道!切成细条的杏仁配上细细条的小鱼干,酥脆,不粘牙,看起来奇葩但好吃到飞飞飞起的组合啊。&/p&&br&&p&&b&- 吃不停指数 ★★★★★&/b&&/p&&p&&b&每一口都像是在吃酥脆的海鲜,芝麻和杏仁的香气去掉了小鱼干的腥味,鲜甜的后味让人想把舌头都吞下去。一袋根本不够吃。&/b&&/p&&br&&p&&b&- 吃不胖指数 ★&/b&&/p&&p&543大卡/100克。杏仁的热量总是稍稍高一些。不过都是独立小包装,很适合平时带几个在身边。&/p&&br&&p&&b&- 不上火指数 ★★★&/b&&/p&&p&杏仁性温,烘烤的小鱼干比较上火,小吃一袋不会爆痘的。&/p&&br&&br&&p&&b&—— 超好吃不上火 NO.1 ——&/b&&/p&&br&&figure&&img src=&https://pic4.zhimg.com/1fc093acaf8f_b.jpg& class=&content_image&&&/figure&&p&&i&(Sunnuts 巴旦木、蔓越莓、葡萄干裹酸奶皮)&/i&&/p&&br&&p&&b&- 上嘴指数 ★★★★★&/b&&/p&&p&&b&里面有酸奶,里面有酸奶,里面有酸奶,重要的事情说三遍。&/b&好吧,只是葡萄干裹了一层酸奶皮,但就一下甩出了其他果干加坚果的组合几条街。&/p&&p&先是巴旦木酥脆的坚果香,然后就感觉蔓越莓的果肉裹上牙齿,在你觉得不过如此的时候,就会突然咬到一个像酸奶QQ糖的裹酸奶葡萄干,好吃到哭出声来。&/p&&br&&p&&b&- 吃不停指数 ★★★★★&/b&&/p&&p&重点是完全不甜腻,而且后味超清新,一口就能吃到果仁香、果肉香和奶香,你能忍住不吃第二口么?&/p&&br&&p&&b&- 吃不胖指数 ★&/b&&/p&&p&570大卡/100克。不过成分这么健康,几乎没有盐。吃一小袋无伤大雅。&/p&&br&&p&&b&- 不上火指数 ★★★★★&/b&&/p&&p&&b&唯一一个没有烘烤谷物的组合,巴旦木性温,蔓越莓性寒,葡萄干性略热,综合而言是完全不爆痘的组合。&/b&&/p&&br&&br&&p&&b&—— 吃吃吃不停指数 NO.1 ——&/b&&/p&&br&&figure&&img src=&https://pic1.zhimg.com/2bbd1dcc07ebd8_b.jpg& class=&content_image&&&/figure&&p&&i&(JORDANS 燕麦片、大麦片、椰蓉、冻覆盆子干、碎烤榛子)&/i&&/p&&br&&p&&b&- 上嘴指数 ★★★★&/b&&/p&&p&整体非常脆,特别脆,连覆盆子干也是脆的,就觉得少了那么点儿乐趣。&/p&&br&&p&&b&- 吃不停指数 ★★★★★★&/b&&/p&&p&&b&吃第一口想吃第二口,吃完一碗想吃第二碗,根本就停不下来。椰蓉、碎烤榛子配上酸甜的覆盆子味,根本没法拒绝。&/b&&/p&&br&&p&&b&- 吃不胖指数 ★★★&/b&&/p&&p&451大卡/100克。还是没有迈过450的大槛,不过已经算是零食界的瘦子了。&/p&&br&&p&&b&- 不上火指数 ★★&/b&&/p&&p&除了一丁丁的椰子能帮忙降低一下这个组合的热气,总的来说,还是一个吃多了会嗓子会干的组合。&/p&&br&&br&&p&&b&—— 吃吃吃不胖指数 NO.1 ——&/b&&/p&&br&&figure&&img src=&https://pic3.zhimg.com/ab8e5dcf431ce541ae75c52cbd1bba1e_b.jpg& class=&content_image&&&/figure&&p&&i&(Back to Nature 全谷物燕麦片、全谷物小麦片、巴旦木)&/i&&/p&&br&&p&&b&- 上嘴指数 ★★★★&/b&&/p&&p&谷物和坚果的味道恰到好处。所有颗粒都小小的,巴旦木也切得很碎,入口有很强的颗粒感,没有奇奇怪怪的味道,整体很清新。&/p&&br&&p&&b&- 吃不停指数 ★★★&/b&&/p&&p&也许是因为入口很清爽的关系,吃完了之后嘴巴也是清清爽爽的,留下淡淡的谷物和坚果香,但是不足以让人很想很想多吃点。&/p&&br&&p&&b&- 吃不胖指数 ★★★★★★&/b&&/p&&p&&b&谷物组合里难以想象的400大卡/100克。两个白馒头就560大卡了。绝对的吃吃吃不胖又有营养的零食组合。&/b&&/p&&br&&p&&b&- 不上火指数 ★★&/b&&/p&&p&如果没有那么多烘烤的话也许能不那么上火,不过搭配一些去火的水果吃的话还是不会爆痘的。&/p&&br&&br&&p&&b&—— 最奇葩口味 NO.1 ——&/b&&/p&&br&&figure&&img src=&https://pic4.zhimg.com/340aa6dd80201bcd86f4e9f3_b.jpg& class=&content_image&&&/figure&&p&&i&(无印良品 蝴蝶脆饼碎)&/i&&/p&&br&&p&&b&- 上嘴指数 ☆ ......又或者 ★★★★★&/b&&/p&&p&这款MUJI出品的魔性零食,要么零分要么五分。原因是:&b&你打开袋子,就是扑面而来的隔壁老王抠脚的味道,臭得那么彻底,那么义无反顾。&/b&&/p&&p&但是放到嘴巴里以后,酥脆感极佳,调味极佳。&/p&&p&喜欢体验不一样的臭味的伙伴们千万不要错过了。这将是臭味食物史上,让你毕生难忘的那一款。&/p&&br&&p&&b&- 吃不停指数 ★★★★★&/b&&/p&&p&&b&芝士、番茄加上罗勒的调味,嗯,虽然每一口吃之前都感觉在闻脚丫子,但吃起来之后,居然完全停不下来!那种悠长的回味,神啊,我这是怎么了。&/b&&/p&&br&&p&&b&- 吃不胖指数 ★★★&/b&&/p&&p&480大卡/100克。加了芝士居然没上500,放心地享受它的味道吧 。&/p&&br&&p&&b&- 不上火指数 ★★&/b&&/p&&p&毕竟还是饼干,说不上火你信么?&/p&&br&&br&&p&&b&—— 最最最终大赢家! ——&/b&&/p&&br&&figure&&img src=&https://pic4.zhimg.com/8de577dae_b.jpg& class=&content_image&&&/figure&&p&&i&(Tilo's 全燕麦片、葡萄干、香蕉片、苹果干、椰肉干)&/i&&/p&&br&&p&&b&- 上嘴指数 ★★★★★★&/b&&/p&&p&&b&每一口都能吃到惊喜的组合。葡萄干、香蕉片、苹果干、椰肉干,谷物和哪一种果干搭配都超好吃。&/b&&/p&&br&&p&&b&- 吃不停指数 ★★★★★★&/b&&/p&&p&&b&嚼完了之后,椰子的浓郁裹着燕麦的香气,让人欲罢不能。&/b&要是你第一口吃到的是香蕉片……估计之后你都会一直在翻找香蕉片了:D&/p&&br&&p&&b&- 吃不胖指数 ★★★★&/b&&/p&&p&433大卡/100克。如果你搭配乐纯FIT一起吃的话,一次只用放40克,即一顿简餐只有231.2大卡,相当于只吃了1个菜包。&/p&&br&&p&&b&- 不上火指数 ★★★★&/b&&/p&&p&&b&烘烤过的燕麦和葡萄干属热性,苹果温性,椰子凉性,香蕉寒性,互补中和,算是加谷物的健康零食中难得不那么上火的。&/b&&/p&&br&&p&------------------------------------&/p&&br&&p&能看到这里,你一定是吃货中的认真咖了。一篇干货满满、价值15000元的吃货攻略到这里就差不多了。&/p&&br&&p&但是!我们岂是213包零食就能满足的了的?我们是执行力超强的吃货好不好。&/p&&br&&p&之所以召集这么多吃遍天下的吃货,因为我们想将把这海量的评测报告运用到研发中,&b&&u&来创造一款吃货的终极福音——超好吃且吃不胖的逆天零食。&/u&&/b&&/p&&br&&p&&b&寻找:有料、能吃的知乎吃货。&/b&&/p&&p&&b&任务:创造一款吃货的终极福音——超好吃且吃不胖的逆天零食。&/b&&/p&&br&&p&所有参与进来的吃货们将一起决定:&/p&&p&1. 选择哪些好吃的单品进行搭配&/p&&p&2. 配方和配料的试吃迭代(继续吃)&/p&&p&3. 超好玩包装和用户体验的设计&/p&&p&4. 食物拍摄(边拍边吃)&/p&&br&&p&&b&而@乐纯的伙伴们 将负责实验室的研发、专业的检测、国内和进口供应商的寻找和谈判、加工工厂的寻找和谈判......最终把这个「超好吃且吃不胖的逆天零食」大批量生产出来,变成现实!&/b&&/p&&br&&p&在这个寒冷的冬天,你肯定不是一个吃货在战斗......&/p&&br&&p&&b&目前为止,这个「超好吃且吃不胖的逆天零食」研发实验室里,已经挤满了这些吃货界的大小咖们.....&/b&&/p&&figure&&img src=&https://pic3.zhimg.com/b01a0fabe28ea_b.jpg& class=&content_image&&&/figure&&br&&p&&b&如果你也想加入,请加艾琳(乐纯首席吃货官,就是上面那位高颜值吃货噢)的微信(ailin_bonnie),并发送搭讪信息:零食。也可以关注她微博@艾婶婶 。&/b&&/p&&br&&p&&a href=&//link.zhihu.com/?target=http%3A//weixin.qq.com/r/FzH85JfEn8rgrdOH92QF& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&weixin.qq.com/r/FzH85Jf&/span&&span class=&invisible&&En8rgrdOH92QF&/span&&span class=&ellipsis&&&/span&&/a& (二维码自动识别)&/p&&br&&p&&i&(高颜值吃货官的二维码在这里。个人微信:ailin_bonnie,微博:@艾婶婶)&/i&&/p&&br&&p&&b&好了,我们继续去抱团吃了。等你噢。&/b&&/p&&br&&p&PS,居然快10000赞了,微信加不过来了大家耐心等一下...最后补两张乐纯首席吃货官的照片和作为感谢吧 :D&/p&&br&&p&PPS,貌似大家都在问如何加入我们,这里是招聘帖哈 →→ &a href=&//link.zhihu.com/?target=http%3A//mp.weixin.qq.com/s%3F__biz%3DMzA3MzU5MDgzMw%3D%3D%26mid%3Didx%3D1%26sn%3Dbff4b620e1cb61a7c6ac%23rd& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&打开这篇内容,可能会点亮你的职业轨迹......&/a&&/p&&br&&figure&&img src=&https://pic4.zhimg.com/1e483e8936adffb2ee88db72bcc8b37f_b.jpg& class=&content_image&&&/figure&
叮咚,小伙伴们,我们又来啦。还记得之前乐纯吃货天团立下的Flag么?——创造一款超好吃且吃不胖的逆天零食。嗯,我们做出来了。历时350天,召集了103位零食达人,吃掉了13斤零食后,我们终于把这个逆天零食研发出来了。它的名字叫「小补给」。食材和配方方…
&figure&&img src=&https://pic3.zhimg.com/v2-09af396db7ed81f7d68f3f5a54333e2e_b.jpg& data-rawwidth=&595& data-rawheight=&340& class=&origin_image zh-lightbox-thumb& width=&595& data-original=&https://pic3.zhimg.com/v2-09af396db7ed81f7d68f3f5a54333e2e_r.jpg&&&/figure&&p&原文地址:&a href=&https://link.zhihu.com/?target=http%3A//www.2cto.com/kf/172.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&2cto.com/kf/1&/span&&span class=&invisible&&72.html&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&&br&&/p&&p&在Android应用中, Activity是最核心的组件, 如何生成一个Activity实例, 可以选择不同的启动模式, 即LaunchMode. 启动模式主要包括: standard, singleTop, singleTask, singleInstance.&br&标准模式在每次启动时, 都会创建实例; 三种单例模式, 会根据情况选择创建还是复用实例. 在Activity启动中, 创建实例的生命周期: onCreate -& onStart -& onR 重用实例的生命周期: onNewIntent -& onResume.&/p&&p&在AndroidManifest的Activity中, 使用launchMode属性, 可以设置启动模式, 默认是standard模式; 使用taskAffinity属性, 并添加包名, 可以设置Activity栈, 默认是当前包名, 只能应用于single模式.&/p&&p&希望通过本文, 可以更好的理解Activity的启动模式(LaunchMode).&/p&&p&观察Activity栈的脚本, 参考第5点 .&/p&&p&adb shell dumpsys activity | sed -n -e '/Stack #/p' -e '/Running activities/,/Run #0/p'&br&本文示例的GitHub 下载地址&/p&&p&&b&1. Standard&/b&&br&标准模式, 启动Activity的默认模式, 被启动的Activity 会运行于 启动的Activity 栈, 因此必须使用Activity的Context启动, 不能使用Application, 否则会报错.&br&如MainActivity启动TestAActivity.&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Stack #1:
Running activities (most recent first):
TaskRecord{3caa65e3 #2711 A=me.chunyu.spike.wcl_activity_launchmode_demo U=0 sz=2}
Run #1: ActivityRecord{36b06e99 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.TestAActivity t2711}
Run #0: ActivityRecord{ me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2711}
Running activities (most recent first):
TaskRecord{27d796c9 #2695 A=com.miui.home U=0 sz=1}
Run #0: ActivityRecord{2e5712cb u0 com.miui.home/.launcher.Launcher t2695}
&/code&&/pre&&/div&&p&栈内由下到上: MainActivity -& TestAActivity.&/p&&p&&b&2. SingleTop&/b&&br&栈顶复用模式. 只有Activity位于栈顶, 重复启动时, 会使用默认实例, 即单例模式; 如果位于栈内, 则仍然会创建实例.&/p&&p&MainActivity启动TestA, TestA启动TestB, TestB启动自身, TestB是单例. 观察栈内情况, TestB只有一份实例, 第二次创建复用.&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Stack #1:
Running activities (most recent first):
TaskRecord{12abf566 #2712 A=me.chunyu.spike.wcl_activity_launchmode_demo U=0 sz=3}
Run #2: ActivityRecord{187d7ff7 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.TestBActivity t2712}
Run #1: ActivityRecord{a me.chunyu.spike.wcl_activity_launchmode_demo/.TestAActivity t2712}
Run #0: ActivityRecord{22f9cce4 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2712}
&/code&&/pre&&/div&&p&栈内: MainActivity -& TestAActivity -& TestBActivity&/p&&p&MainActivity启动TestA, TestA启动TestB, TestB启动TestC, TestC启动TestB, TestB是单例. 观察栈内情况, 由于TestC是栈顶, TestC启动TestB, TestB不是栈顶, 重新创建TestB实例, 则保留两份TestB.&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Stack #1:
Running activities (most recent first):
TaskRecord{ #2715 A=me.chunyu.spike.wcl_activity_launchmode_demo U=0 sz=5}
Run #4: ActivityRecord{1e70110b u0 me.chunyu.spike.wcl_activity_launchmode_demo/.TestBActivity t2715}
Run #3: ActivityRecord{c7f4dce u0 me.chunyu.spike.wcl_activity_launchmode_demo/.TestCActivity t2715}
Run #2: ActivityRecord{254536cd u0 me.chunyu.spike.wcl_activity_launchmode_demo/.TestBActivity t2715}
Run #1: ActivityRecord{36b2da15 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.TestAActivity t2715}
Run #0: ActivityRecord{3a1c4a6a u0 me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2715}
&/code&&/pre&&/div&&p&栈内: MainActivity -& TestAActivity -& TestBActivity -&TestCActivity -& TestBActivity&/p&&p&&b&3. SingleTask&/b&&br&栈内复用模式, 只要Activity在一个栈中存在, 多次调用时, 都不会创建实例, 即单例模式.&br&情况包含以下几种:&/p&&p&(1) 任务栈不存在, 初次启}

我要回帖

更多关于 www.49pppp.com 的文章

更多推荐

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

点击添加站长微信