- 浏览: 1578066 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (603)
- T_java (145)
- T_script&ASP (51)
- T_C/C++ (25)
- T_PowerBuilder (11)
- T_Database (53)
- T_odoo (7)
- T_应用服务器 (50)
- T_专_条形码 (6)
- T_专_负载均衡器 (4)
- T_操作系统 (94)
- T_信息安全 (41)
- T_专_搜索引擎 (14)
- T_L_PHP (58)
- T_L_Delphi (18)
- T_L_.NET、C#、VisualStudio (25)
- T_L_Objective-C (6)
- T_移动开发 (53)
- T_网络 (109)
- T_大数据 (2)
- T_嵌入式 (2)
- T_小众技术 (24)
- T_未分类 (58)
- L_旅游印记 (1)
- L_生活随笔 (48)
- L_中国文化 (18)
- L_户外与生存 (0)
最新评论
-
csbean4004:
不知道哪传来得恶习,发帖子不好好发,故意弄错一些东西,很讨厌
让HTML5支持后置摄像头 -
withthewind:
终于找到一个可以用的了。。。
如何用VBA取得Word文档中的标题前面的序号 -
busbby:
兄弟,无法下载,说文件不完整
一个好用的Outlook ost格式文件转pst文件的工具 -
yijavakevin:
密码啊~解压密码多少?
一个二维条形码组件 -
vipbooks:
你给的那个链接根本无法下载,跳到官网看了下最新版12M,但点下 ...
十步以内完成精细web打印
身为重度Node.js用户,我也来说说我的理解吧。
计算机语言和技术平台很多时候不是谁更好谁更差的问题,而是谁更合适的问题,这里我们从语言和生态系统两个维度来坐下简要的对比。
语言的对比
JavaScript和Java从语言的设计上来说,虽然都含有Java但是是完全不同的两种语言,简单的说:
JavaScript
JavaScript是其实没法简单的用一句话来解释其设计,大了说,我们可以称他为一种多范式的语言(通常这个词用在C++身上),小了说我们可以把它当成是一种基于原型链的面向对象动态语言来看待。正是这种“灵活性”给各种奇技淫巧带来了可能性,表面上这减少了代码量,给码农们带来了幸福,而实际上,正是因为这种灵活性导致了程序在运行过程中很容易出现难以调试的Bug,而Bug的日志会让人摸不着头脑。
再者JavaScript设计上对异步没有很好的支持,对于Node这种完全异步的平台而言,编写复杂逻辑的应用程序简直就是灾难,举个例子:
通常,同步的逻辑是这样的:
function getForgeMetadata(cid, itemId) {
var character = getCharacter(cid);
var item = getItem(itemId);
var itemDesc = getItemDesc(item.type);
var forgeLevel = getForgeLevel(item);
return getForgeMetadata(character, itemDesc, forgeLevel);
}
然而,如果我们采用node.js中标准的回调格式来编写代码的话,您的代码会变成这样:
function getForgeMetadata(cid, itemId, cb) {
getCharacter(cid, function(err, character) {
if (err) return cb(err);
getItem(itemId, function(err, item) {
if (err) return cb(err);
getItemDesc(item.type, function(err, itemDesc) {
if (err) return cb(err);
var forgeLevel = getForgeLevel(item);
getForgeMetadata(character, itemDesc, forgeLevel, cb);
});
});
});
}
看到那一长串的if (err) return cb(err);你会不会有种想要自杀的感觉,后来终于社区也看不下去了就弄了个async库出来,但基本上差别也不太大,再后来有了promise(通常使用库q来实现),情况略有好转,代码可以变成这样:
function getForgeMetadata(cid, itemId) {
return getCharacter(cid)
.then(function(character) {
return getItem(itemId)
.then(function(item) {
return {'character': character, 'item': item};
});
};
}).then(function(meta) {
return getItemDesc(meta.item.type)
.then(function(itemDesc) {
meta.itemDesc = itemDesc;
return meta;
});
}).then(function(meta) {
var forgeLevel = getForgeLevel(meta.item);
return getForgeMetadata(meta.character, meta.itemDesc, forgeLevel);
});
}
然而这坑爹货的代码还是一样的难读和难以维护啊,终于有一个人看不下去了,他就是 @赵颉,他把C#中的await语义移植到了js中,弄了个Wind.js出来,这样大家终于能写人话了:
function getForgeMetadata(cid, itemId) {
var character = $await(getCharacter(cid));
var item = $await(getItem(itemId));
var itemDesc = $await(getItemDesc(item.type));
var forgeLevel = getForgeLevel(item);
return $await(getForgeMetadata(character, itemDesc, forgeLevel));
}
然而顽固不化的Node.js社区断然拒绝了这绝妙的设计,老赵也停止了Wind.js的开发,最终版本的Wind.js也没加入只差一步的调试功能,我们刚进到蜜罐就又被迫迁移到promise上来,继续痛苦的旅程。
如果你认为这就是Node.js的唯一噩梦的话,你就太天真了。完全异步化带来的另一个问题就是调试困难。由于异步过程中的循环是利用回调来实现的,如果你恰好有个本地额缓存,然后缓存命中时就直接同步调用了回调函数,那么恭喜你,你会遇到栈溢出的问题(假设循环10000次,将会有10000*n的栈深度,想象一下吧),所以通常情况下,大家会采用setImmediate函数来调用回调函数,其结果是,发生错误时的栈信息可能是类似这样的:
Cannot call undefined
at onImmediate
(不准确,大概就这意思)
可是你该怎么知道是哪个坑爹的漏传了这个cb函数导致它是undefined?
除此之外,JavaScript设计上是非常不严谨的一门语言,导致有大量陷阱存在,你试着做做这里的题目就明白这玩意儿有多坑了。
http://javascript-puzzlers.herokuapp.com
Java
说完了JavaScript的部分,我们再来看看Java。Java的定义很简单,它是一种面向对象的静态语言。然而坑爹的sun(oracle)在java语言的成长之路上做出了一个又一个的错误决定,其中首当其冲的就是采用类型抹除的方式实现泛型,简单的说List<string>和List<WhatTheFuckClass>居然是同一个类型。
同样的Java也没有await语义的支持,所以你看到的Java程序通常情况下是同步的,基本上有2种方式,要嘛来一个请求,开一个线程,要嘛一个固定大小的线程池,请求在池中逐个执行,反正总归会有线程因为IO或者其他原因处在sleep状态,其结果就是没办法(很难)实现单服高并发的承载能力。
再者由于Java的表达力实在不怎么样,所以通常情况下Java代码又臭又长。
平台的对比
Node.js相对来说是一个比较优秀的平台,从很早的版本开始(记得是0.6还是0.8)就已经把npm作为默认组件打包在一起了。npm对于Node.js生态圈的意义在于,用户再也不需要手工管理依赖关系,对于刚开始使用的用户来说,也非常容易搭建起工作环境。你可以直接使用npm install package_name来安装包,也可以直接在package.json中声明,然后使用npm install来自动解析和安装依赖,这绝对是相对其他平台优秀很多的地方。
然后Node.js的执行环境有着不可避免的局限性,就是它终究是个单线程的执行环境,没法直接发挥多核、多CPU的服务器的优势。所以通常大型Node.js项目会采用多进程的架构(比如网易的pomelo,我们公司的游戏服务器也是类似的架构),而不同的进程间采用restful的接口进行通信,而这样的代价就是花费大量的CPU时间在JSON序列化和反序列化的过程中,总之就是坑啊。
Java的生态环境可以说是非常优秀,不可否认的,Java平台拥有这个世界上最完善的,而且是经过生产环境验证的工业级的库。不过由于设计上就是同步的语言,也没有C#中的await机制,整个平台都是同步的,对于高并发的环境来说,确实做起来会有一定的困难。
结论
1)Node.js和Java本身不产生竞争关系
2)他们谁也不会消亡,如果非要说谁更可能消亡的话,我觉得是Node.js
3)如果你要做的是小型项目,或者逻辑非常简单的项目,可以选择Node.js,因为开发、调试都很很快。
4)如果你要做的是逻辑简单,而并发大的项目,可以选择Node.js,它还是很适合左右游戏的聊天服务器,长连接消息推送服务器之类的项目的。
5)如果你在做一个大规模项目(5人以上协作),还是用C#吧,C#并不是跟Windows绑定的语言,非windows平台上的Mono也非常好用。
希望这洋洋洒洒的胡言乱语对你有用~
计算机语言和技术平台很多时候不是谁更好谁更差的问题,而是谁更合适的问题,这里我们从语言和生态系统两个维度来坐下简要的对比。
语言的对比
JavaScript和Java从语言的设计上来说,虽然都含有Java但是是完全不同的两种语言,简单的说:
JavaScript
JavaScript是其实没法简单的用一句话来解释其设计,大了说,我们可以称他为一种多范式的语言(通常这个词用在C++身上),小了说我们可以把它当成是一种基于原型链的面向对象动态语言来看待。正是这种“灵活性”给各种奇技淫巧带来了可能性,表面上这减少了代码量,给码农们带来了幸福,而实际上,正是因为这种灵活性导致了程序在运行过程中很容易出现难以调试的Bug,而Bug的日志会让人摸不着头脑。
再者JavaScript设计上对异步没有很好的支持,对于Node这种完全异步的平台而言,编写复杂逻辑的应用程序简直就是灾难,举个例子:
通常,同步的逻辑是这样的:
function getForgeMetadata(cid, itemId) {
var character = getCharacter(cid);
var item = getItem(itemId);
var itemDesc = getItemDesc(item.type);
var forgeLevel = getForgeLevel(item);
return getForgeMetadata(character, itemDesc, forgeLevel);
}
然而,如果我们采用node.js中标准的回调格式来编写代码的话,您的代码会变成这样:
function getForgeMetadata(cid, itemId, cb) {
getCharacter(cid, function(err, character) {
if (err) return cb(err);
getItem(itemId, function(err, item) {
if (err) return cb(err);
getItemDesc(item.type, function(err, itemDesc) {
if (err) return cb(err);
var forgeLevel = getForgeLevel(item);
getForgeMetadata(character, itemDesc, forgeLevel, cb);
});
});
});
}
看到那一长串的if (err) return cb(err);你会不会有种想要自杀的感觉,后来终于社区也看不下去了就弄了个async库出来,但基本上差别也不太大,再后来有了promise(通常使用库q来实现),情况略有好转,代码可以变成这样:
function getForgeMetadata(cid, itemId) {
return getCharacter(cid)
.then(function(character) {
return getItem(itemId)
.then(function(item) {
return {'character': character, 'item': item};
});
};
}).then(function(meta) {
return getItemDesc(meta.item.type)
.then(function(itemDesc) {
meta.itemDesc = itemDesc;
return meta;
});
}).then(function(meta) {
var forgeLevel = getForgeLevel(meta.item);
return getForgeMetadata(meta.character, meta.itemDesc, forgeLevel);
});
}
然而这坑爹货的代码还是一样的难读和难以维护啊,终于有一个人看不下去了,他就是 @赵颉,他把C#中的await语义移植到了js中,弄了个Wind.js出来,这样大家终于能写人话了:
function getForgeMetadata(cid, itemId) {
var character = $await(getCharacter(cid));
var item = $await(getItem(itemId));
var itemDesc = $await(getItemDesc(item.type));
var forgeLevel = getForgeLevel(item);
return $await(getForgeMetadata(character, itemDesc, forgeLevel));
}
然而顽固不化的Node.js社区断然拒绝了这绝妙的设计,老赵也停止了Wind.js的开发,最终版本的Wind.js也没加入只差一步的调试功能,我们刚进到蜜罐就又被迫迁移到promise上来,继续痛苦的旅程。
如果你认为这就是Node.js的唯一噩梦的话,你就太天真了。完全异步化带来的另一个问题就是调试困难。由于异步过程中的循环是利用回调来实现的,如果你恰好有个本地额缓存,然后缓存命中时就直接同步调用了回调函数,那么恭喜你,你会遇到栈溢出的问题(假设循环10000次,将会有10000*n的栈深度,想象一下吧),所以通常情况下,大家会采用setImmediate函数来调用回调函数,其结果是,发生错误时的栈信息可能是类似这样的:
Cannot call undefined
at onImmediate
(不准确,大概就这意思)
可是你该怎么知道是哪个坑爹的漏传了这个cb函数导致它是undefined?
除此之外,JavaScript设计上是非常不严谨的一门语言,导致有大量陷阱存在,你试着做做这里的题目就明白这玩意儿有多坑了。
http://javascript-puzzlers.herokuapp.com
Java
说完了JavaScript的部分,我们再来看看Java。Java的定义很简单,它是一种面向对象的静态语言。然而坑爹的sun(oracle)在java语言的成长之路上做出了一个又一个的错误决定,其中首当其冲的就是采用类型抹除的方式实现泛型,简单的说List<string>和List<WhatTheFuckClass>居然是同一个类型。
同样的Java也没有await语义的支持,所以你看到的Java程序通常情况下是同步的,基本上有2种方式,要嘛来一个请求,开一个线程,要嘛一个固定大小的线程池,请求在池中逐个执行,反正总归会有线程因为IO或者其他原因处在sleep状态,其结果就是没办法(很难)实现单服高并发的承载能力。
再者由于Java的表达力实在不怎么样,所以通常情况下Java代码又臭又长。
平台的对比
Node.js相对来说是一个比较优秀的平台,从很早的版本开始(记得是0.6还是0.8)就已经把npm作为默认组件打包在一起了。npm对于Node.js生态圈的意义在于,用户再也不需要手工管理依赖关系,对于刚开始使用的用户来说,也非常容易搭建起工作环境。你可以直接使用npm install package_name来安装包,也可以直接在package.json中声明,然后使用npm install来自动解析和安装依赖,这绝对是相对其他平台优秀很多的地方。
然后Node.js的执行环境有着不可避免的局限性,就是它终究是个单线程的执行环境,没法直接发挥多核、多CPU的服务器的优势。所以通常大型Node.js项目会采用多进程的架构(比如网易的pomelo,我们公司的游戏服务器也是类似的架构),而不同的进程间采用restful的接口进行通信,而这样的代价就是花费大量的CPU时间在JSON序列化和反序列化的过程中,总之就是坑啊。
Java的生态环境可以说是非常优秀,不可否认的,Java平台拥有这个世界上最完善的,而且是经过生产环境验证的工业级的库。不过由于设计上就是同步的语言,也没有C#中的await机制,整个平台都是同步的,对于高并发的环境来说,确实做起来会有一定的困难。
结论
1)Node.js和Java本身不产生竞争关系
2)他们谁也不会消亡,如果非要说谁更可能消亡的话,我觉得是Node.js
3)如果你要做的是小型项目,或者逻辑非常简单的项目,可以选择Node.js,因为开发、调试都很很快。
4)如果你要做的是逻辑简单,而并发大的项目,可以选择Node.js,它还是很适合左右游戏的聊天服务器,长连接消息推送服务器之类的项目的。
5)如果你在做一个大规模项目(5人以上协作),还是用C#吧,C#并不是跟Windows绑定的语言,非windows平台上的Mono也非常好用。
希望这洋洋洒洒的胡言乱语对你有用~
发表评论
-
SpringBoot Fat Jar解压运行
2018-06-28 21:40 2184SpringBoot已经成为当前最流行的微服务 ... -
一句话实现五星评分显示
2018-06-05 08:31 946Python: rate = 1 #rate 取值 ... -
来算google的可视化编程工具——Blockly,不仅仅是玩具
2017-10-16 21:34 32718Blockly - 来自Google的可 ... -
安卓动态分析工具 Inspeckage
2017-08-07 08:46 0工具介绍 一个基于Xposed 开发的应用动态分析工具 g ... -
Android逆向之旅---静态方式破解微信获取聊天记录和通讯录信息
2017-08-07 08:37 0一、猜想数据存放路径 微信现在是老少皆宜,大街小巷都在使用 ... -
破解微信数据库 并查询数据上传服务器
2017-08-07 08:29 0由于工作需求破解了微信的数据库 并获取想要的信息上传服 ... -
安卓黑科技之HOOK详解
2017-08-07 08:21 0本文带大家进入到安卓另一个世界 互联网攻防大战 Xpos ... -
安卓逆向之基于Xposed-ZjDroid脱壳
2017-08-07 08:18 0前言 之前介绍了普通常见的反编译模式 但对于使用了 360 ... -
十步以内完成精细web打印
2017-06-21 11:44 7291注意: 康虎云报表组 ... -
pdf2htmlEX:把PDF转换成HTML的神器
2017-03-15 19:00 2721pdf2htmlEX:将 PDF 转为 HTML 网页 反 ... -
子div撑不开父div的几种解决方法
2017-02-26 11:39 2756子div撑不开父div的几种解决方法 子div撑不开 ... -
浏览器端精准打印或套打组件
2017-01-18 13:05 6640注意: 康虎云报表 ... -
让ie6 7 8 9支持html5 websocket
2016-12-23 20:52 2195结果: 从github上的 web ... -
如何让三列div中间那个自适应宽度
2016-12-03 18:46 667效果如图: 直接上代码,具体看注释: < ... -
两个相同放大镜叠加焦距计算
2016-09-16 19:47 2269关于两个相同放大镜叠加后焦距的计算公式: F={ ( f ... -
疯狂软件对Oracle放弃Java EE的看法
2016-08-14 22:38 473来源:http://javaligang ... -
Windown下最简安装nodejs和npm
2016-06-20 21:03 637Windown下最简安装nodejs和npm 一、下 ... -
几个Java相关的思维导图
2016-03-17 13:07 911来源:http://blog.csdn.net/jackf ... -
八款优秀的Linux天文学软件
2016-02-21 20:31 2862八款优秀的Linux天文学软件 天文学是一门研究恒 ... -
jasperReport Applet 打印
2016-02-01 16:33 824Applet方式的原理是本地下载Applet以及Jas ...
相关推荐
Node.js 这是一个执行环境(JavaScript运行时),用于在Web浏览器以外的地方使用JavaScript,并在服务器环境中使用JavaScript。 支持大规模的网络应用程序开发。Node.js网络应用程序了解每个Node.js网络应用程序和...
Node.js是基于Chrome JavaScript运行时建立的一个平台,实际上它是对Google Chrome V8引擎进行了封装;该文档介绍从javascirpt、V8、优缺点、涉及领域、知识点,阐述了Node.js的开发涉及到领域和潜力。
Node.js 对比 Python:优点、缺点和用例(csdn)————程序
但缺点也很明显,由于 Node.js 是单线程程序,如果长时间运算,会导致 CPU 不能及时释放,所以并不适合 CPU 密集型应用。 当然,也不是没有办法解决这个问题。虽然 Node.js 不支持多线程,但是可创建多子进程来执行...
Mincemeat-node 是使用Node.js实现的极简MapReduce框架,可以快速的部署投入工作,免去Hadoop繁琐的配置,享受随心大数据。Mincemeatpy实现的是一种非常简单的MapReduce模型,仅仅实现了任务的分布计算,并没有类似...
最近,Node.js 和 Python 都因其广泛的特性和功能在市场上大受欢迎。在你开发Web应用程序的...用一种简单易懂的语言来说,Node.js是一个服务器端平台,它是在Google Chrome的JavaScript引擎(称为V8引擎)上开发的。Nod
主要介绍了什么是Node.js,Node.js能做什么,Node.js的优缺点,Node.js的例子等,需要的朋友可以参考下
Liblog是一个简单易用的Markdown博客系统,它是基于开源框架thinkJS(使用 ES6/7 特性开发 Node.js 框架)开发的nodejs项目 需要mysql数据库支持,具有管理后台功能,更新博客分为普通文章和markdown文章,markdown...
本文由浅入深给大家介绍node.js stream api,具体详情请看下文吧。 基本介绍 在 Node.js 中,读取文件的方式有两种,一种是用 fs.readFile ,另外一种是利用 fs.createReadStream 来读取。 fs.readFile 对于每个 ...
UInt1-31(有一些缺点) 浮动16/32/64 启用的压缩: 无压缩 打包位 左翼 放气(具有浮点或水平预测变量支持) JPEG格式 自动选择要阅读的概述级别 通过图像窗口或边界框和选定波段进行子设置 将样本读取到单独...
1. 后端接口打包到本地运行(缺点:每次后端更新都要去测试服下一个更新包,还要在本地搭建java运行环境,麻烦) 2. CORS跨域:后端接口在返回的时候,在header中加入’Access-Control-Allow-origin’:* 之类的(有...
Python 和 Ruby 也有这样的框架,但因为在实际使用中会不可避免地用到含有同步代码的库,因此没能成长起来,而在 Node.js 之前,JavaScript 的服务器端编程几乎是空白,所以 Node.js 才得以建立起了一个所有 IO 均为...
将缓存与Redis和Node.js结合使用 概括 快取 快取类型 客户端缓存(浏览器) Web服务器上的缓存 应用内缓存 在每种情况下缓存的优缺点 使用缓存即服务 雷迪斯 比较Redis和Memcached 安装和使用Redis和Node.js进行...
这是从节点开始使用某些库的好方法,但是存在以下缺点: 性能-与直接从Node.js环境中调用库C或C ++ API相比,对shell命令的调用花费更多的时间和更多的资源。 错误处理程序-有时您无法以正确的方式拦截和处理错误。...
在Node.js中有相当多的解决方案,其中有语言内置功能,也有开源社区贡献的开发库。下面咱们来看一下比较流行的几种方式。 在开始之前,请先在自己的计算机上安装最新版的node.js和npm。 HTTP – 标准库 首先是标准...
有几个可用于node.js的配置模块。 每种方法都有其优点和缺点,但是没有一个项目可以视为所有用例的最佳配置选项。 某些应用程序需要复杂的配置,可以从中央服务器获取。 其他人只想在应用启动时加载一个简单的JSON...
一、对于一个刚入门node.js的朋友来说,一定要了解一些基础概念: 今年我正式进入社会后,发现自己所知道的IT方面的知识,真的只是牛毛,原来人外有人,山外有山,还需要继续努力。下面是一些我的自学习心得,发出来...
当前只有一个针对node / javascript的嵌入式事件存储实现,即https://github.com/adrai/node-eventstore 这是一个不错的项目,但是有一些缺点: 它的API完全基于事件流,因此,要提交新事件,首先需要检索完整的...
markdownlint 用于Markdown / CommonMark文件的Node.js样式检查器和lint工具。安装npm install markdownlint --save-dev总览标记语言旨在易于阅读,编写和理解。 它成功了-它的灵活性既是优点也是缺点。 可能有多种...
支持为python、lua、js等多种常见脚本语言生成C++组件包装代码,swig使用者只需要编写C++代码和swig配置文件即可开发各种脚本语言的C++组件,不需要了解各种脚本语言的组件开发框架,缺点是不支持javascript的回调,...