【读书笔记】《编写高效的JavaScript程序》

为什么80%的码农都做不了架构师?>>>   hot3.png

看到一篇文章,http://www.csdn.net/article/2012-11-20/2811887-writing-fast-memory-efficient-javascript/2

里面有个网页针对 原型链,模块化,模块化加缓存,进行了比对测试:http://jsperf.com/prototypal-performance/12

测试用例及测试结果如下:(chrome下)

测试代码如下:

<script>Benchmark.prototype.setup = function() {Klass1 = function() {}Klass1.prototype.foo = function() {log('foo');}Klass1.prototype.bar = function() {log('bar');}Klass2 = function() {var foo = function() {log('foo');},bar = function() {log('bar');};return {foo: foo, bar: bar}}var FooFunction = function() {log('foo');};var BarFunction = function() {log('bar');};Klass3 = function() {return {foo: FooFunction, bar: BarFunction}}};
</script>

愚见:

先不说这个测试案例是否真能体现性能。只从代码书写和学习过程来说。

如果能摒弃一个function写完一整个功能的做法,进入模块化编程。这是个进步。

再说上述所谓缓存,其实就是给函数闭包加了一个引用,因为引用的存在,所以闭包不会按通常情况被销毁。如果有人这样写,大量的全局变量,对于需要长期维护更新的项目来说这简直就是灾难。我自己就深受其害,而且是被自己所坑。绝对不能推广这种做法。有了开头就没结尾,养成习惯就难改了。(如果是在一个规模庞大前端依然成体系的公司,万一人家要求,还是不得不写,不过这种情况下,就连命名都会有诸多规范和要求吧。)

最推荐的,自然是原型链的写法。不过真心表示需要根据项目需要和能力而为,否则写出来的东西简直就是惨不忍睹。不管怎样,学习中。

-----------------------------------------------

原文摘录如下:

Addy Osmani是谷歌公司Chrome团队中的一名程序开发工程师。他是一位JavaScript爱好者,曾经编写过一本开放源码方面的书籍《Learning JavaScript Design Patterns》以及《Developing Backbone Applications》。为Modernizr和jQuery社区贡献了开源项目,目前正在从事‘Yeoman’项目,旨在为开发者提供一系列健壮的工具、程序库和工作流,帮助他们快速构建出漂亮、引人注目的Web应用。本文作者将带领大家探索高效编写代码的测试验证方法。文章内容如下:

JavaScript引擎包括Google V8(Chrome,Node)都是专为快速执行大型JavaScript程序而设计的。在开发过程中,如果你在乎内存使用率和性能情况,那么你应该会关心在用户的浏览器中JavaScript引擎背后是怎么样的。无论是V8、SpiderMonkey (Firefox)、Carakan (Opera)、Chakra (IE) 还是其他,有了它们可以帮助你更好的优化应用程序。

我们应该时不时地询问自己:

  • 我还能做些什么使代码更加有效?

  • 主流的JavaScript引擎做了哪些优化?

  • 什么是引擎无法优化的,我能期待利用垃圾回收进行清洁吗?

当涉及到编写高效的内存和快速创建代码时总会出现一些常见的弊端,在这篇文章中我们将探索高效编写代码的测试验证方法。

一、JavaScript如何在V8中工作?

如果你对JS引擎没有较深的了解,开发一个大型Web应用也没啥问题,就好比会开车的人也只是看过引擎盖而没有看过车盖内的引擎一样(这里将Web网页比如成汽车)。Chrome浏览器是我的优先选择,这里我将谈下V8的核心组件:

  • 一个基本的编译器,在代码执行前分析JavaScript、生成本地机器代码而非执行字节代码或是简单的解释,该段代码之初不是高度优化的。

  • V8用对象模型“表述”对象。在JavaScript中,对象是一个关联数组,但是V8中,对象被“表述”为隐藏类,这种隐藏类是V8的内部类型,用于优化后的查找。

  • 运行时分析器监视正在运行的系统并优化“hot”(活跃)函数。(比如,终结运行已久的代码)

  • 通过运行时分析器把优化编译器重新编译和被运行时分析器标识为“hot”的代码 ,这是一种有效的编译优化技术,(例如用被调用者的主体替换函数调用的位置)。

  • V8支持去优化,也就是说当你发现一些假设的优化代码太过乐观,优化编译器可以退出已生成的代码。

  • 垃圾回收,了解它是如何工作的,如同优化JavaScript一样同等重要。

二、垃圾回收

垃圾回收是内存管理的一种形式,它试图通过将不再使用的对象修复从而释放内存占用率。垃圾回收语言(比如JavaScript)是指在JavaScript这种垃圾回收语言中,应用程序中仍在被引用的对象不会被清除。手动消除对象引用在大多数情况下是没有必要的。通过简单地把变量放在需要它们的地方(理想情况下,尽可能是局部作用域,即它们被使用的函数里而不是函数外层),一切将运作地很好。

在JavaScript中强制执行垃圾回收是不取的,当然,你也不会想这么做,因为垃圾回收进程被运行时控制着,它知道什么时候才是适合清理代码的最好时机。

1.“消除引用”的误解(De-Referencing Misconceptions)

在JavaScript中回收内存在网上引发了许多争论,虽然它可以被用来删除对象(map)中的属性(key),但有部分开发者认为它可以用来强制“消除引用”。建议尽可能避免使用delete,在下面的例子中delete o.x 的弊大于利,因为它改变了o的隐藏类,使它成为通用的慢对象。

var o = { x: 1 };  
delete o.x; // true  
o.x; // undefined

目的是为了在运行时避免修改活跃对象的结构,JavaScript引擎可以删除类似“hot”对象,并试图对其进行优化。如果该对象的结果没有太大改变,超过生命周期,删除可能会导致其改变。

对于null是如何工作也是有误解的。将一个对象引用设置为null,并没有使对象变“空”,只是将它的引用设置为空而已。使用o.x= null比使用delete会更好些,但可能也不是很必要。

var o = { x: 1 };  
o = null;  
o; // null  
o.x // TypeError

如果这个引用是最后一个引用对象,那么该对象可进行垃圾回收;倘若不是,那么此方法不可行。注意,无论您的网页打开多久,全局变量不能被垃圾回收清理。

var myGlobalNamespace = {};

当你刷新新页面时,或导航到不同的页面,关闭标签页或是退出浏览器,才可进行全局清理;当作用域不存在这个函数作用域变量时,这个变量才会被清理,即该函数被退出或是没有被调用时,变量才能被清理。

经验法则:

为了给垃圾回收创造机会,尽可能早的收集对象,尽量不要隐藏不使用的对象。这一点主要是自动发生,这里有几点需要谨记:

  1. 正如之前我们提到的,手动引用在合适的范围内使用变量是个更好的选择,而不是将全局变量清空,只需使用不再需要的局部函数变量。也就是说我们不要为清洁代码而担心。

  2. 确保移除不再需要的事件侦听器,尤其是当DOM对象将要被移除时。

  3. 如果你正在使用本地数据缓存,请务必清洁该缓存或使用老化机制来避免存储那些不再使用的大量数据。

2.函数(Functions)

正如我们前面提到的垃圾回收的工作原理是对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。下面的例子能够更好的说明这一点:

function foo() {  
var bar = new LargeObject();  
bar.someCall();   
}

当foo返回时,bar自动指向垃圾回收对象,这是因为没被调用,这里我们将做个对比:

function foo() {  var bar = new LargeObject();  bar.someCall();  return bar;  
}  
// somewhere else  
var b = foo();

这里有个调用对象且被一直调用着直到这个调用交给b(或是超出b范围)。

3.闭包(Closures)

当你看到一个函数返回到内部函数,该内部函数可以访问外部函数,即使外部函数正在被执行。这基本上是一个封闭的,可以在特定的范围内设置变量的表达式。比如:

function sum (x) {  function sumIt(y) {  return x + y;  };  return sumIt;  
}  // Usage  
var sumA = sum(4);  
var sumB = sumA(3);  
console.log(sumB); // Returns 7

在sum调用上下文中生成的函数对象(sumIt)是无法被回收的,它被全局变量(sumA)所引用,并且可以通过sumA(n)调用。

这里有个示例演示如何访问largeStr?

var a = function () {  var largeStr = new Array(1000000).join('x');  return function () {  return largeStr;  };  
}();

我们可以通过a():

var a = function () {  var smallStr = 'x';  var largeStr = new Array(1000000).join('x');  return function (n) {  return smallStr;  };  
}();

此时,我们不能访问了,因为它是垃圾回收的候选者。

4.计时器(Timers)

最糟糕的莫过于在循环中泄露,或者在setTimeout()/setInterval()中,但这却是常见的问题之一。

var myObj = {  callMeMaybe: function () {  var myRef = this;  var val = setTimeout(function () {  console.log('Time is running out!');  myRef.callMeMaybe();  }, 1000);  }  
};

如果我们运行:

myObj.callMeMaybe();

在计时器开始前,我们看到每一秒“时间已经不多了”,这时,我们将运行:

myObj = null;

三、当心性能陷阱

除非你真正需要,否则永远不要优化代码。在V8中你能轻易的看到一些细微的基准测试显示比如N比M更佳,但是在真实的模块代码中或是在实际的应用程序中测试,这些优化所带来的影响要比你想象中要小的多。

创建一个模块,这里有三点:

  1. 采用本地的数据源包含ID数值

  2. 绘制一个包含这些数据的表格

  3. 添加事件处理程序,当用户点击的任何单元格时切换单元格的css class

如何存储数据?如何高效的绘制表格并追加到DOM?怎样处理表单上的事件?

注意:下面的这段代码,千万不能做:

var moduleA = function () {  return {  data: dataArrayObject,  init: function () {  this.addTable();  this.addEvents();  },  addTable: function () {  for (var i = 0; i < rows; i++) {  $tr = $('<tr></tr>');  for (var j = 0; j < this.data.length; j++) {  $tr.append('<td>' + this.data[j]['id'] + '</td>');  }  $tr.appendTo($tbody);  }  },  addEvents: function () {  $('table td').on('click', function () {  $(this).toggleClass('active');  });  }  };  
}();

很简单,但是却能把工作完成的很好。

请注意,直接使用DocumentFragment和本地DOM方法生成表格比使用jQuery更佳,事件委托通常比单独绑定每个td更具备高性能。jQuery一般在内部使用DocumentFragment,但是在这个例子中,通过内循环调用代码append() ,因此,无法在这个例子中进行优化,但愿这不是一个诟病,但请务必将代码进行基准测试。

这里,我们通过opting for documentFragment提高性能,事件代理对简单的绑定是一种改进,可选的DocumentFragment也起到了助推作用。

var moduleD = function () {  return {  data: dataArray,  init: function () {  this.addTable();  this.addEvents();  },  addTable: function () {  var td, tr;  var frag = document.createDocumentFragment();  var frag2 = document.createDocumentFragment();  for (var i = 0; i < rows; i++) {  tr = document.createElement('tr');  for (var j = 0; j < this.data.length; j++) {  td = document.createElement('td');  td.appendChild(document.createTextNode(this.data[j]));  frag2.appendChild(td);  }  tr.appendChild(frag2);  frag.appendChild(tr);  }  tbody.appendChild(frag);  },  addEvents: function () {  $('table').on('click', 'td', function () {  $(this).toggleClass('active');  });  }  };  }();

我们不妨看看其他提供性能的方法,也许你曾读过使用原型模式或是使用JavaScript模板框架进行高度优化。但是使用这些仅针对可读的代码。此外,还有预编译。我们一起来实践下:

moduleG = function () {};  moduleG.prototype.data = dataArray;  
moduleG.prototype.init = function () {  this.addTable();  this.addEvents();  
};  
moduleG.prototype.addTable = function () {  var template = _.template($('#template').text());  var html = template({'data' : this.data});  $tbody.append(html);  
};  
moduleG.prototype.addEvents = function () {  $('table').on('click', 'td', function () {  $(this).toggleClass('active');  });  
};  var modG = new moduleG();

事实证明,选择模板和原型并没有给我们带来多大好处。

四、V8引擎优化技巧:

特定的模式会导致V8优化产生故障。很多函数无法得到优化,你可以在V8平台使用--trace-opt file.js搭配d8实用程序。

如果你关心速度,那么尽最大努力确保单态函数(functions monomorphic),确保变量(包括属性,数组和函数参数)只适应同样的隐藏类包含的对象。

下面的代码演示了,我们不可这么做:

function add(x, y) {  return x+y;  
}  add(1, 2);  
add('a','b');  
add(my_custom_object, undefined);

未初始化时不要加载和执行删除操作,因为它们并没有输出差异,这样做反而会使程序变得更慢。不要编写大量函数,函数越多越难优化。

1.Objects使用技巧:

适应构造函数来创建对象。这将确保所创建的所有对象具备相同的隐藏类并有帮助避免更改这些类。

在程序或者复杂性上不要限制多种对象类型。(原因:长原型链中倾向于伤害,只有极少数的对象属性得到一个特殊的委托)对于活跃对象保持短原型链以及低字段计数。

2.对象克隆(Object Cloning)

对象克隆对于应用开发者来说是一种常见的现象。虽然在V8中这是实现各种类型问题的基准,但是当你进行复制时,一定要当心。当复制较大的程序时通常很会慢,因此,尽量不要这么做。在JavaScript循环中此举是非常糟糕的。这里有个最快的技巧方案,你不妨学习下:

function clone(original) {  this.foo = original.foo;  this.bar = original.bar;  
}  
var copy = new clone(original);

3.模块模式中的缓存功能

在模块模式中使用缓存功能也许在性能方面会有所提升。请参阅下面的例子,通过jsPerf test测试。注,使用这种方法比依靠原型模式更佳。

Performance improvements

推荐:这是测试原型与模块模式性能代码

 // Prototypal pattern  Klass1 = function () {}  Klass1.prototype.foo = function () {  log('foo');  }  Klass1.prototype.bar = function () {  log('bar');  }  // Module pattern  Klass2 = function () {  var foo = function () {  log('foo');  },  bar = function () {  log('bar');  };  return {  foo: foo,  bar: bar  }  }  // Module pattern with cached functions  var FooFunction = function () {  log('foo');  };  var BarFunction = function () {  log('bar');  };  Klass3 = function () {  return {  foo: FooFunction,  bar: BarFunction  }  }  // Iteration tests  // Prototypal  var i = 1000,  objs = [];  while (i--) {  var o = new Klass1()  objs.push(new Klass1());  o.bar;  o.foo;  }  // Module pattern  var i = 1000,  objs = [];  while (i--) {  var o = Klass2()  objs.push(Klass2());  o.bar;  o.foo;  }  // Module pattern with cached functions  var i = 1000,  objs = [];  while (i--) {  var o = Klass3()  objs.push(Klass3());  o.bar;  o.foo;  }  
// See the test for full details

4.数组使用技巧:

一般情况下,我们不要删除数组元素。它是使数组过渡到较慢的内部表现形式。当密钥集变得稀疏时,V8最终将切换到字典模式,这是变慢的原因之一。

五、应用优化技巧:

在Web应用领域里,速度就是一切。没有用户希望在启动电子表格时需要等上几秒钟,或者花上几分钟时间来整理信息。这也是为什么在性能方面,需要格外注意的一点,有人甚至将编码阶段称为至关重要的一部分。

理解和提升性能方面是非常有用的,但它也有一定的难度。这里推荐几个步骤来帮你解决:

  1. 测试:在应用程序中找到慢的节点 (~45%)

  2. 理解:查找问题所在(~45%)

  3. 修复:(~10%)

当然,还有许多工具或是技术方案帮助解决以上这些问题:

1.基准测试。在JavaScript上有许多方法可进行基准测试。

2.剖析。Chrome开发工具能够很好的支持JavaScript分析器。你可以使用这些性能进行检测,哪些功能占用的时间比较长,然后对其进行优化。最重要的是,即使是很小的改变也能影响整体的表现。关于这款分析工具,这里有份详细的介绍。

3.避免内存泄露-3快照技术。谷歌开发团队通常会使用Chrome开发工具包括Gmail来帮助他们发现和修复内存泄露;此外,3 snapshot也是不错的选择。该技术允许在程序中记录一些行为、强制垃圾回收、查询,如果DOM节点无法返回预期的基线上,3 snapshot帮助分析确定是否存在内存泄露。

4.单页面程序上的内存管理。当你在编写单页程序时(比如,AngularJS,Backbone,Ember)),内存管理非常重要,他们从未得到刷新。这就意味着内存泄露很明显。在移动单页程序上存在着巨大的陷阱,因为内存有限,长期运行的程序比如email客户端或者社交网络应用。因此,它肩负着巨大的责任。

Derick发表了这篇《memory pitfalls》教您如何使用Backbone.js以及如何进行修复。Felix Geisend&ouml;rfer的这篇在Node中调试内存泄露也值得一读。

5.最小化回流。回流是指在浏览器中用户阻止此操作,所以它是有助于理解如何提高回流时间,你可以使用DocumentFragment一个轻量级的文档对象来处理。

6.Javascript内存泄露检测器。由Marja H&ouml;ltt&auml;和Jochen Eisinger两人开发的这款工具,你不妨试试。

7.V8 flags调试优化和内存回收。Chrome支持通过flags和js-flags flag获取更详细的输出:

例如:

"/Applications/Google Chrome/Google Chrome" --js-flags="--trace-opt --trace-deopt"

Windows用户运行chrome.exe --js-flags="--trace-opt --trace-deopt"。

当开发应用时,可以使用下面的V8 flags:

  • trace-opt –日志名称的优化功能,显示优化跳过的代码

  • trace-deopt –记录运行时将要“去优化”的代码。

  • trace-gc – 对每次垃圾回收时进行跟踪

结束语:

正如上面提到的,在JavaScript引擎中有许多隐藏的陷阱,世界上没有什么好的银弹能够帮助你提高性能,只有通过在测试环境中进行优化,实现最大的性能收益。因此,了解引擎如何输出和优化代码可以帮助你调整应用程序。

因此,测试它、理解它、修复它,如此往复!

英文出自:Coding.smashingmagazine

转载于:https://my.oschina.net/maomi/blog/92028

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/301943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cloudera将被私有化,Hadoop时代或将落幕

北京时间 6 月 1 日晚&#xff0c;据 TechCrunch 报道 [1]&#xff0c;KKR 和 CD&R 将以 53 亿美元收购 Cloudera&#xff0c;Cloudera 将被私有化。截止到本文发稿时&#xff08;11 点 49 分&#xff09;&#xff0c;Cloudera 股票报价 15.94 美元&#xff0c;涨幅 23.95%…

mysql group_concat去重_MySQL group_concat() 函数用法

MySQL group_concat() 函数用法在使用 group by对数据进行分组后&#xff0c;如果需要对 select 的数据项进行字符串拼接&#xff0c;这时就需要用到group_concat()函数。1、基本用法group_concat()完整语法如下&#xff1a;group_concat([DISTINCT] 要连接的字段 [Order BY AS…

请问:如何写出没有BUG的代码?

全世界只有3.14 % 的人关注了数据与算法之美1947年9月9日&#xff0c;美国海军准将 Grace Hopper 在哈佛学院计算机实验室里使用 Mark II 和 Mark III 计算机进行研究工作。她的团队跟踪到 Mark II 上的一个错误&#xff0c;操作人员发现是由于一只飞蛾钻到了 Mark II 的继电器…

非常适合新手的redis cluster搭建过程

Redis集群演进过程Redis单节点主从复制&#xff1a;复制主要实现了数据的多机备份&#xff0c;以及对于读操作的负载均衡和简单的故障恢复。故障恢复无法自动化&#xff1b;写操作无法负载均衡&#xff1b;存储能力受到单机的限制。哨兵&#xff08;Sentinel&#xff09;&#…

各类环境渗透测试简述

2019独角兽企业重金招聘Python工程师标准>>> 各类环境渗透测试简述 一、渗透测试概念 渗透测试 (penetration test)并没有一个标准的定义&#xff0c;国外一些安全组织达成共识的通用说法是&#xff1a;渗透测试是通过模拟恶意黑客的攻击方法&#xff0c;来评估计算…

预售┃一张纸一幅图,竟然提高了10倍的学习和工作效率!?

▲卢sir特别推荐点击上图进入玩酷屋人类大脑的容量远远超出一般人的想象&#xff0c;时到21世纪的今天&#xff0c;我们对大脑的运用远远不够。大脑机能的使用率基于我们的思维模式&#xff0c;而思维导图正是开发大脑中最有效的利器&#xff01;之前小木给大家推荐了一套基于少…

入门K8s:一键脚本搭建Linux服务器集群

前言好久没有写系列博客了&#xff0c;本文主要是对网上文章的总结篇&#xff0c;主要是将安装和运行代码做了一次真机实验&#xff0c;亲测可用。文章内包含的脚本和代码&#xff0c;多来自于网络&#xff0c;也有我自己的调整和配置&#xff0c;文章末尾对参考的文献做了列举…

数据库系统原理及mysql应用教程第二版_数据库系统原理及MySQL应用教程(第2版十三五普通高等教育规划教材)...

导语内容提要本书共19章&#xff0c;全面地讲述了数据库技术的基本原理和应用。主要内容包括&#xff1a;数据库概述、信息与数据模型、关系代数与关系数据库理论、数据库设计方法、MySQL的安装与使用、MySQL存储引擎与数据库操作管理、MySQL表定义与完整性约束控制、MySQL数据…

Eclipse 安装配置总结(WST WTP)(转)

为什么80%的码农都做不了架构师&#xff1f;>>> Eclipse 安装配置总结(WST WTP)(转) Eclipse 是最流行的功能强大的java IDE&#xff0c;有丰富的插件&#xff0c;配合插件可以作为j2ee、c、c、.net等开发工具。需要安装插件才能支持Web开发和其他应用的开发&#…

2019最佳年会,新东方6名员工冒着离职的风险,在年会上怒怼老板

全世界只有3.14 % 的人关注了数据与算法之美今天早上&#xff0c;数据汪打开微信朋友圈一看&#xff0c;发现大家都在疯传昨晚北京新东方学校年会节目《释放自我》。新东方员工们把歌曲《沙漠骆驼》的歌词给改编过后&#xff0c;把许多奋战在一线的员工心声都给唱出来了&#x…

mysql列增减_Mysql基本操作——增减改查

1 创建数据库&#xff1a;两种方法&#xff1a;create database my_db;createdatabase if not exists my_db;2 删除数据库&#xff1a;两种方法&#xff1a;drop databasemy_db;drop database if exists my_db;3 创建表&#xff1a;createtable table_name (column_name column…

使用mysql-proxy 快速实现mysql 集群 读写分离

为什么80%的码农都做不了架构师&#xff1f;>>> 使用mysql-proxy 快速实现mysql 集群 读写分离 目前较为常见的mysql读写分离分为两种&#xff1a; 1、 基于程序代码内部实现&#xff1a;在代码中对select操作分发到从库&#xff1b;其它操作由主库执行&#xff1…

50万年薪程序员,被百万网民怒喷后,却迎来大撕逼

全世界只有3.14 % 的人关注了数据与算法之美前几天&#xff0c;我们年轻气盛的小卢写了一篇关于“程序员锁库跑路&#xff0c;最终致创业公司倒闭”的文章&#xff0c;语言有些偏激&#xff0c;数据汪在此替小卢给大伙道个歉&#xff0c;至于为何不让他本人来呢&#xff1f;因为…

.NET轻量级配置中心AgileConfig

描述基于NetCore开发的轻量级配置中心&#xff0c;部署简单、配置简单&#xff0c;使用简单&#xff0c;可以根据个人或者公司需求采用。部署简答&#xff0c;最少只需要一个数据节点&#xff0c;支持docker部署支持多节点分布式部署来保证高可用配置支持按照应用隔离&#xff…

人生苦短,我用Python!

在大数据时代&#xff0c;信息更新非常快速&#xff0c;计算机语言也犹如雨后春笋般被我们所熟知。C语言、C、Java等可谓是各领风骚、独占鳌头&#xff0c;而Python则是一门近几年崛起很快也很火的编程语言。虽说编程语言难分好坏&#xff0c;各有千秋。但Python到底有什么魔力…

预售┃没有标题,配得上这款“俄罗斯方块”

▲数据汪特别推荐点击上图进入玩酷屋在之前的文章时&#xff0c;马斯提到数学存在一种现象叫“梯次掉队”&#xff0c;原因在于孩子的数学思维地基没有打牢。&#xff08;传送门&#xff09;提到初中孩子需要空间想象能力时&#xff0c;很多父母疑惑为何需要&#xff1f;关于这…

读Getting Started With Windows PowerShell笔记

使用中Powershell的操作跟Linux中的终端操作很多地方是一致的&#xff0c;当然&#xff0c;还是有着Windows自己的特色&#xff0c;比如&#xff0c;不分大小写。之前命令行中的命令大部分在这里也可以用&#xff0c;而且用法一样。选中后点右键&#xff0c;即复制到剪切板。不…

NET问答: String 和 string 到底有什么区别?

咨询区 Peter O.&#xff1a;开门见山&#xff0c;参考如下例子&#xff1a;string s "Hello world!"; String s "Hello world!";请问这两者有什么区别&#xff0c;在实际使用上要注意一些什么&#xff1f;回答区 Derek Park&#xff1a;string 是 C# 中…

LVS负载均衡-NET、DR模式配置

模型一&#xff1a;NAT模型的配置 实验环境&#xff1a; 采用VMware虚拟机&#xff0c;版本6.0.5 操作系统&#xff1a;Red Hat Enterprise Linux 5 (2.6.18) 虚拟机1&#xff1a;充当Director&#xff1a;网卡1(桥接):192.168.0.33&#xff08;对外&#xff09;&#xff0c;网…

编程语言的“别样”编年史

全世界只有3.14 % 的人关注了数据与算法之美代码是一门语言&#xff0c;这门语言搭建了人与计算机沟通的桥梁。通过编写代码&#xff0c;人类可以“命令”计算机开发网页、开发软件、搭建游戏... ... 这门语言并不是上帝的发明&#xff0c;它是前辈们发挥聪明才智创造出来的&am…