2016年1月22日星期五

阮一峰的网络日志

阮一峰的网络日志


白领的消亡

Posted: 21 Jan 2016 05:14 PM PST

(说明:本文原载2016年第三期《财新周刊》

新年伊始,咨询公司埃森哲(Accenture)公布了一项调查

他们找到17个行业的1700个白领人士,问了同样的一个问题。

"你觉得计算机对你构成威胁吗?"

结果令人震惊。35%的人回答Yes。他们觉得在未来,机器可以自动完成他们现在的工作,因此职位可能保不住。最焦虑的就是科技行业的白领,回答Yes的人高达50%,其次是银行业,比例是49%。

一位评论家一针见血地指出,技术革命进入新阶段。以前,消失的是依靠体力的职位,现在就连一部分依靠智力的职位也在消失。

"以前,技术革命只是对蓝领工人不利,贸易全球化和自动化技术使得低技能工人,失去工作或者一直拿着低工资。而现在,技术革命开始威胁那些有技能的人了,人工智能、大数据、办公自动化正在快速地消灭办公室职位。"

白领,一般是指那些有技能的人士,比如管理人员、财务人员、金融业者、律师等等,劳动主要以智力投入为主。通常需要坐在办公室里,衣着整洁,穿白衬衫,所以叫做白领。

以前,白领是令人羡慕的工作,家长期待自己的孩子成为白领。可是,信息技术高速发展,机器的判断能力和处理能力,使得很多办公室职位变得不必要了。

美国曾经有一种工作,叫做"税务顾问"(tax consultant)。因为税法非常复杂,普通人根本搞不清楚,所以你会请他帮你报税。这样就不用自己填写复杂的表格,而且他还会告诉你各种节税诀窍。可是,现在有报税网站和软件,你只要在电脑前回答几个问题,电脑就会告诉你应该如何报税,简单、快速又便宜。那些税务顾问发现,自己没法与软件竞争,只能纷纷转业。这个职业在美国已经开始消失了。

我再举一个更常见的例子。银行职员(比如柜台操作员)以前是一份可靠的工作,有稳定的薪水可以养家。现在不是了。如今,你去银行存款或者取款,会找柜台人员吗?不会,大多数时候你直接去ATM机。24小时服务的ATM,正在取代一天工作8小时的柜台人员。

如果你说,柜台操作员不算严格意义的白领,那么信贷员算不算?银行都有一个信贷部门,这是银行利润的关键来源。信贷员负责寻找贷款对象和审核贷款,业绩往往与贷款挂钩,如果做得好,收入非常可观。

可是,现在有了"自动贷款",比如淘宝的"花呗"业务,它会根据消费者的购买历史、信用记录和支付能力,自动计算出每个人不一样的贷款额度。你只要点一下同意按钮,贷款一秒钟就到帐。整个过程完全自动化,根本不需要信贷员参与。将来每个人、每家企业的数据都储存在数据库里,计算机自动评估能不能向你贷款、可以贷多少,那么谁还需要信贷员?

如果仔细考察,你会发现很多银行职位都有消失的危险,比如风险控制、信用记录、外汇交易等等,软件都可以完成。对于现在这些职位上的白领人员来说,这是非常可怕的压力。

未来什么工作才能算白领?说实话,没有人知道。因为很难估计技术会发展到什么地步。厉以宁教授最近说,将来没有白领和蓝领之分。

"以后很多工作会由机器人去做,所以蓝领和白领的界限将来会逐步消失。当人们都在计算机边上的时候,你能说谁是白领、谁是蓝领吗?说不出来的,这个界限在逐渐消失,可能十年、二十年以后就没有了。大家都在运用计算机操纵机器人。"

如果你的职位有可能被计算机取代,一个现实的问题是,你该怎么办?跟机器竞争是不可能的,你没它可靠,没它耐劳,没它便宜。

许多人说,可以接受培训,学习新的技能,实现人生转型。这实际上很难做到。比如,现在很热门的一种职位,叫做"数据科学家"或者"数据工程师"。但是,一个装配线工人,不太可能经过几个月的培训,就转变为一个数据工程师。让我这么说吧,不仅他不太可能,你也不太可能。任何没有专业基础的人转变为数据从业人员的机会,就是四个字:"微乎其微"。

技术革命对人类社会的形态,已经产生了深刻的改变。从上个世纪90年代开始,低技能劳动者的报酬一直无法提高。现在,轮到白领阶层了。他们已经或者即将发现,自己处于挣扎之中,没有职业前景,工作报酬同蓝领工人一样陷入泥潭,无法提高。对于整个社会来说,技术造成的贫富差距将日益严重。这种趋势已经在世界许多国家出现,政府完全束手无策。

那么,有没有计算机不能取代的工作,所需要的技能是计算机无法学会的?答案是有的。吴晓波把难以被机器替代的能力,称为"柔软的能力"。他总结出四种。

(1)个性化服务能力。软件都是统一的算法,个性化服务很难做到。

(2)人格魅力的能力。机器提供的服务,不会有人格魅力,也不会感动人心。

(3)创意的能力。计算机最难以与人类竞争的,就是创造力。

(4)决策领导的能力(即企业家的能力)。机器没有办法团结领导一群人,齐心协力完成一个使命。

作为个人来说,人生规划的时候,应该尽量发展这些能力,才能避免与机器"抢工作"。

(完)

文档信息

npm 模块安装机制简介

Posted: 20 Jan 2016 05:42 PM PST

npm 是 Node 的模块管理器,功能极其强大。它是 Node 获得成功的重要原因之一。

正因为有了npm,我们只要一行命令,就能安装别人写好的模块 。

 $ npm install  

本文介绍 npm 模块安装机制的细节,以及如何解决安装速度慢的问题。

一、从 npm install 说起

npm install 命令用来安装模块到node_modules目录。

 $ npm install <packageName> 

安装之前,npm install会先检查,node_modules目录之中是否已经存在指定模块。如果存在,就不再重新安装了,即使远程仓库已经有了一个新版本,也是如此。

如果你希望,一个模块不管是否安装过,npm 都要强制重新安装,可以使用-f--force参数。

 $ npm install <packageName> --force 

二、npm update

如果想更新已安装模块,就要用到npm update命令。

 $ npm update <packageName> 

它会先到远程仓库查询最新版本,然后查询本地版本。如果本地版本不存在,或者远程版本较新,就会安装。

三、registry

npm update命令怎么知道每个模块的最新版本呢?

答案是 npm 模块仓库提供了一个查询服务,叫做 registry 。以 npmjs.org 为例,它的查询服务网址是 https://registry.npmjs.org/

这个网址后面跟上模块名,就会得到一个 JSON 对象,里面是该模块所有版本的信息。比如,访问 https://registry.npmjs.org/react,就会看到 react 模块所有版本的信息。

它跟下面命令的效果是一样的。

 $ npm view react  # npm view 的别名 $ npm info react $ npm show react $ npm v react 

registry 网址的模块名后面,还可以跟上版本号或者标签,用来查询某个具体版本的信息。比如, 访问 https://registry.npmjs.org/react/v0.14.6 ,就可以看到 React 的 0.14.6 版。

返回的 JSON 对象里面,有一个dist.tarball属性,是该版本压缩包的网址。

 dist: {   shasum: '2a57c2cf8747b483759ad8de0fa47fb0c5cf5c6a',   tarball: 'http://registry.npmjs.org/react/-/react-0.14.6.tgz'  }, 

到这个网址下载压缩包,在本地解压,就得到了模块的源码。npm installnpm update命令,都是通过这种方式安装模块的。

四、缓存目录

npm installnpm update命令,从 registry 下载压缩包之后,都存放在本地的缓存目录。

这个缓存目录,在 Linux 或 Mac 默认是用户主目录下的.npm目录,在 Windows 默认是%AppData%/npm-cache。通过配置命令,可以查看这个目录的具体位置。

 $ npm config get cache $HOME/.npm 

你最好浏览一下这个目录。

 $ ls ~/.npm  # 或者 $ npm cache ls 

你会看到里面存放着大量的模块,储存结构是{cache}/{name}/{version}

 $ npm cache ls react ~/.npm/react/react/0.14.6/ ~/.npm/react/react/0.14.6/package.tgz ~/.npm/react/react/0.14.6/package/ ~/.npm/react/react/0.14.6/package/package.json 

每个模块的每个版本,都有一个自己的子目录,里面是代码的压缩包package.tgz文件,以及一个描述文件package/package.json

除此之外,还会生成一个{cache}/{hostname}/{path}/.cache.json文件。比如,从 npm 官方仓库下载 react 模块的时候,就会生成registry.npmjs.org/react/.cache.json文件。

这个文件保存的是,所有版本的信息,以及该模块最近修改的时间和最新一次请求时服务器返回的 ETag 。

 {   "time":{     "modified":"2016-01-06T23:52:45.571Z",     // ...   },   "_etag":"\"7S37I0775YLURCFIO8N85FO0F\"" } 

对于一些不是很关键的操作(比如npm searchnpm view),npm会先查看.cache.json里面的模块最近更新时间,跟当前时间的差距,是不是在可接受的范围之内。如果是的,就不再向远程仓库发出请求,而是直接返回.cache.json的数据。

.npm目录保存着大量文件,清空它的命令如下。

 $ rm -rf ~/.npm/* # 或者 $ npm cache clean 

五、模块的安装过程

总结一下,Node模块的安装过程是这样的。

  1. 发出npm install命令
  2. npm 向 registry 查询模块压缩包的网址
  3. 下载压缩包,存放在~/.npm目录
  4. 解压压缩包到当前项目的node_modules目录

注意,一个模块安装以后,本地其实保存了两份。一份是~/.npm目录下的压缩包,另一份是node_modules目录下解压后的代码。

但是,运行npm install的时候,只会检查node_modules目录,而不会检查~/.npm目录。也就是说,如果一个模块在~/.npm下有压缩包,但是没有安装在node_modules目录中,npm 依然会从远程仓库下载一次新的压缩包。

这种行为固然可以保证总是取得最新的代码,但有时并不是我们想要的。最大的问题是,它会极大地影响安装速度。即使某个模块的压缩包就在缓存目录中,也要去远程仓库下载,这怎么可能不慢呢?

另外,有些场合没有网络(比如飞机上),但是你想安装的模块,明明就在缓存目录之中,这时也无法安装。

六、--cache-min 参数

为了解决这些问题,npm 提供了一个--cache-min参数,用于从缓存目录安装模块。

--cache-min参数指定一个时间(单位为分钟),只有超过这个时间的模块,才会从 registry 下载。

 $ npm install --cache-min 9999999 <package-name> 

上面命令指定,只有超过999999分钟的模块,才从 registry 下载。实际上就是指定,所有模块都从缓存安装,这样就大大加快了下载速度。

它还有另一种写法。

 $ npm install --cache-min Infinity <package-name> 

但是,这并不等于离线模式,这时仍然需要网络连接。因为现在的--cache-min实现有一些问题。

(1)如果指定模块不在缓存目录,那么 npm 会连接 registry,下载最新版本。这没有问题,但是如果指定模块在缓存目录之中,npm 也会连接 registry,发出指定模块的 etag ,服务器返回状态码304,表示不需要重新下载压缩包。

(2)如果某个模块已经在缓存之中,但是版本低于要求,npm会直接报错,而不是去 registry 下载最新版本。

npm 团队知道存在这些问题,正在重写 cache。并且,将来会提供一个--offline参数,使得 npm 可以在离线情况下使用。

不过,这些改进没有日程表。所以,当前使用--cache-min改进安装速度,是有问题的。

七、离线安装的解决方案

社区已经为npm的离线使用,提出了几种解决方案。它们可以大大加快模块安装的速度。

解决方案大致分成三类。

第一类,Registry 代理。

上面三个模块的用法很类似,都是在本机起一个 Registry 服务,所有npm install命令都要通过这个服务代理。

 # npm-proxy-cache $ npm --proxy http://localhost:8080 \   --https-proxy http://localhost:8080 \   --strict-ssl false \   install  # local-npm $ npm set registry http://127.0.0.1:5080  # npm-lazy $ npm --registry http://localhost:8080/ install socket.io 

有了本机的Registry服务,就能完全实现缓存安装,可以实现离线使用。

第二类,npm install替代。

如果能够改变npm install的行为,就能实现缓存安装。npm-cache 工具就是这个思路。凡是使用npm install的地方,都可以使用npm-cache替代。

 $ npm-cache install 

第三类,node_modules作为缓存目录。

这个方案的思路是,不使用.npm缓存,而是使用项目的node_modules目录作为缓存。

上面两个工具,都能将项目的node_modules目录打成一个压缩包,以后安装的时候,就从这个压缩包之中取出文件。

(完)

文档信息