js学习笔记——局部变量和全局变量

js 的局部变量和全局变量 大纲 如何声明局部变量和全局变量 js 变量作用域基于特有的作用域链 js 没有块级作用域(ES5-) 函数中声明的变量在整个函数中都有定义 声明局部变量和全局变量 全局变量——定义在函数外的变量 局部变量——函数内部声明的变量 var a = "global"; function getLocal() { var a = "local"; console.log(a); } getLocal(); console.log(a); local global a = "global"; function getLocal() { a = "local"; console.log(a); b = "local"; console.log(b); } getLocal(); console.log(a); console.log(b); local local local local 疑问: 函数外的 a 为什么变成 local? 函数外为什么可以访问 b? 解析: 函数体内部,局部变量优先级比同名全局变量高 函数体内声明变量不使用 var,会暴露在全局上下文中,和现有变量冲突,并覆盖同名全局变量 变量作用域链 每当 js 执行时会有一个对应的执行环境被创建(每一个方法在自己独有的执行环境中执行) 执行环境中的重要部分——函数的调用对象(存储相应函数的局部变量) 函数的执行环境包含了调用对象,调用对象的属性就是函数的局部变量,每个函数在这样的执行环境中执行。函数之外的代码在另一个环境中执行,包含了全局变量。 作用域链 对象组成的列表或链...

2018-01-19 16:34:02 · 2 分钟 · 345 字

js学习笔记——闭包

JS 闭包探析。What exactly the Closure is? 计算机术语 闭包:引用了自由变量的函数。这个被引用的自由变量和这个函数一同存在,即使已经离开了创造它的环境。 变量作用域 全局 局部 函数内部可直接读取全局变量 var n1 = 9; function f1() { alert(n1); } f1(); 9 因为变量声明在 Global,全局可见,它的子当然可以访问到 函数外部无法直接读取函数内部的局部变量 function f2() { var n2 = 99; } alert(n2); n2 is not defined 因为函数是子,函数外部是父,父无法直接访问到子的局部变量 函数内部变量如果未用 var 声明则为全局变量 function f3() { n3 = 999; } f3(); alert(n3); 999 不管变量是在函数内还是函数外声明,如果没有使用 var 声明变量,就会是全局可见的 于是此时的 n3 是 Global.n3 从外部读取局部变量 ~想起了 Java 的反射~ 方法:在函数内部再定义一个函数 function f4() { var n4 = 9999; function f5() { alert(n4); } } 解析:...

2018-01-19 15:33:28 · 2 分钟 · 276 字

比特币协议是如何工作的(译)

本文翻译自 13 年一篇关于比特币协议的深度解析文章 成千上万篇文章为了解释比特币这一线上、点对点的货币而撰写。大多数文章对于其底层加密协议都只给出一些简短的解释,却忽略了很多细节。甚至那些文章常常掩盖重点进行更深入的研究。我这篇文章的目的是以一种清晰、容易理解的方式解释隐藏在比特币协议后面的主要思想。我们将从第一原则开始,对于比特币如何工作建立一个广义的理论上的理解,然后再深挖其细节,检查比特币交易的原始数据。 以细节的方式理解协议是一项困难的工作。人们转而接受比特币,并从事投机关于如何通过比特币致富、比特币吧是否泡沫,比特币是否意味着税收结束的一天等等。这很有趣,但是严重限制你理解它。理解比特币的协议细节打开了难以进入的远景。特别是,理解比特币内建脚本语言的基础会使得使用比特币创造新的金融工具成为可能,比如智能合同。反过来,新的金融工具可以被用来创造新的市场并缔造人类行为新的集合形式。聊聊这些趣事吧! 我会在后面的文章中描述比特币脚本和一些概念,比如智能合同。这篇文章集中解释比特币协议的核心。理解这篇文章你需要对公钥加密以及与其紧密关联的数字签名概念比较熟悉。我将同样假定你对加密散列概念熟悉。以上这些都没有特别难理解的。基本概念都会在大学的大一数学课程或者计算机课程中教授。这些概念很优雅,所以如果你对于他们不是很熟悉,我建议你先花一点时间熟悉一下。 也许看上去比较神奇,比特币的基础是密码学。比特币不是一种货币?不是一种发送秘密信息的方式?事实上,比特币需要解决的事情大部分是安全事务——确保人们不能互相窃取,或者伪造等等。在原子世界我们通过一些设备,例如锁、保险箱、签名、银行金库实现安全。在比特世界我们通过加密实现安全。这也是为什么比特币的核心是加密协议。 我在这篇文章中的策略是分阶段建立起比特币。我会通过解释一种非常简单的数字货币开始,所基于的思想几乎显而易见。我们将称其信息货币(Infocoin),以区分于比特币。当然,我们第一个版本的信息币会有很多不足,然后我们会经过多个迭代,每个迭代介绍仅仅一或两个新的想法。经过多个迭代后,我们将达到完整的比特币协议。我们将重新发明了比特币。 这种策略比起我一次性解释整个比特币协议要慢。但是当你通过这样一次性解释的方式理解了比特币机制时,再去理解比特币为什么这样设计就会很困难。这种通过慢迭代的解释方式优势在于可以让你对于比特币每一个元素理解得更加犀利。 最后,我应该提及对于比特币我也是个新手。我从 2011 年开始松散地关注(在 20 世纪 90 年代末开始关注加密数字货币),但直到今年早些时候才着重关注比特币协议的细节。所以我将非常感激对于我误解部分的指正。另外在本篇文章中我还包含了很多“留给读者的问题”——在我写作过程中对于新冒出的问题的一些笔记。你会发现这很有趣,但你也可以把它们全部跳过以免丢失全文的线索。 第一步:签名意图信 所以我们该如何设计一个数字货币呢? 从表面上来看,数字货币听起来是不可能的。假设某个人,让我们称其 Alice,她有一些电子钱想花掉。如果 Alice 想使用一串比特字符作为钱,我们如何才能阻止她反复使用相同的比特字符串呢?否则将意味着会产生无穷无尽的钱。或者假如我们可以通过某种方式解决这个问题,但我们如何才能防止其他人伪造这样一串比特字符并用来偷取 Alice 的钱呢? 这些只是众多问题中的两个,必须被克服以为了使用信息作为货币。 作为信息币的第一个版本,让我们找到一个方法使得 Alice 可以使用一串字符(非常原始和不完整)作为货币的形式,以某种至少保证她的货币不会被伪造的方式。假设 Alice 想给 Bob 一个信息币。为了这么做,Alice 写下一行字符串“我,爱丽丝,给 Bob 一个信息币”。然后她用私钥给这条信息做了数字签名,并告知全世界 这段签过名的字符串。 (顺便提一下,我使用首字母大写的 Infocoin 表示信息币协议及一般概念,用首字母小写的 infocoin 特指货币面值,类似用法很常见,虽然在比特币的世界不通用) 这并不是一个令人非常影响深刻的数字货币原型。但它的确有一些优点。世界上的任何人(包括 Bob)可以使用 Alice 的公钥去确认 Alice 的确是“我,爱丽丝,给 Bob 一个信息币”这条信息签名的主人。没有其他人可以造出这条比特信息。但反过来,Alice 也可以说“不,我没说要给 Bob 一个信息币”。所以这个协议建立在 Alice 真的想给 Bob 一个信息币。同样的事实——没有其他人可以构造这样一条签名信息——也给予 Alice 一些防止其他人伪造的有限保护。当然,在 Alice 创建她的这条信息后也可能其他人复制了这条信息,这样的话伪造是可能的。但无法从头伪造。这两种属性——Alice 建立企图的部分和防止伪造的有限保护部分,是这个协议值得注意的特征。 我在这个协议中没有(非常)准确地讲数字货币是什么。为了使其明确:特指这条信息本身,例如,这行比特字符串展示了数字货币“我,爱丽丝,给 Bob 一个信息币”。后面的协议类似,我们所有数字货币的形式只是会越来越复杂。 使用序列号来使得货币被唯一标识 第一个版本的信息币的问题在于 Alice 可以一次又一次地继续向 Bob 发送相同的签名消息。假定 Bob 收到了十份“我,爱丽丝,给 Bob 一个信息币”这样的拷贝签名信息。意味着 Alice 向 Bob 发送了十个不同的信息币吗?她的信息是巧合复制出来的吗?可能她只是试图戏弄 Bob 使其相信她给了他十个不同的信息币,当这条信息向全世界证明才表示她真的企图传送一个信息币。...

2018-01-18 09:38:05 · 2 分钟 · 353 字

webpack学习笔记

关于 Webpack 基础使用的整理 背景 网站由网页模式进化成 Webapp 模式 网站运行在高级浏览器中,使用 HTML5、CSS3、ES6 等新技术 webapp 通常是单页面应用(每一个视图通过异步方式加载,导致页面初始化和使用过程会加载更多的 js 代码) 前端开发基于多语言、多层次编码和组织工作,交付基于浏览器,需要保证代码和资源在浏览器端快速优雅的加载和更新,亟需模块化系统 传统方式 <script src="module1.js"></scrpti> <script src="module2.js"></scrpti> <script src="module3.js"></scrpti> ... 弊端 全局作用域(定义在 window 对象下)下易造成变量冲突 文件只能按照脚本引入的顺序加载 需要主观解决模块和代码库的依赖关系 大型项目中资源难以管理,长期积累导致代码库混乱不堪 CommonJS 服务端的 Node.js 遵循 CommonJS 规范 核心思想 允许模块通过 require 方法来同步加载要依赖的其他模块 通过 exports 或 module.exports 导出需要暴露的接口 require("module"); require("../file.js"); exports.doStuff = function() {}; module.exports = someValue; 优势 服务端模块便于重用 NPM 中已有大量可用模块包(20w) 简单易用 缺陷 同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的 不能非阻塞的并行加载多个模块 ES6 模块 ES6 标准增加了 js 语言层面的模块体系定义 ES6 的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。...

2018-01-17 11:41:10 · 3 分钟 · 582 字

如何设计良好的API并且为什么这很重要(译)

本文翻译自 Effective Java 作者 Joshua Bloch 撰写的一篇关于 API 设计的分享 API 可以是公司最大的资产之一 客户投入巨资:购买、撰写、学习(售前一系列培训) 停止使用 API 导致的花费令人望而却步(如果不使用 API 可能要花费更多) 成功的公共 API 赢得客户 也可以成为公司最大的负债之一 糟糕的 APIs 将导致无休止的电话技术支持(需要接听很多来自客户的反映) 公共的 APIs 是永久的——一次去做正确事情的机会 为什么 API 设计对于你来说很重要 如果你编码,你就是一个 API 的设计者 良好的代码应该是模块化的——每一个模块都有一个 API 有用的模块往往被重用 对于 API 方面的思考将提高代码的质量 好的 API 所具备的特征 易于学习 易于使用,甚至无需任何文档 不易误用 易于阅读并且对所使用的代码部分易于维护 足够强大以满足需求 易于拓展 适用于大众 大纲 API 设计的过程 一般原则 类设计 方法设计 异常设计 API 重构设计 I API 设计的过程 收集需求——以一种健康的程度怀疑 通常你会得到建议的解决方法作为替代方案 可能存在更好的解决方案 你的工作是去提取出真正的需求 应采取用例的形式 可以更容易、更有意义地建立更普遍的东西 从简短的规范页开始比较理想 在这个阶段,敏捷胜过完整性 和尽可能多的人谈(原文:Bounce spec off as many people as possible) 倾听他们的输入并认真对待 如果你保持规范简短,那么将易于修改 充分自信 这涉及到编码时也很必要 尽早写给你的 API 以下应开始于在你实现 API 之前...

2018-01-16 11:38:31 · 4 分钟 · 845 字

vultr账单解析及使用ssr在vultr搭建代理

今天就之前疑惑不解的 vultr 账单做了一波分析,终于算是破案了,借此也记录一下服务器搭建 ssr 的详细步骤。 一开始打开 vultr 账单,我是懵比的 这里面的加加减减使我很费解,不知道 vultr 的记账方式,也不知道它的扣款方式(原因是我从开通账户后就毫无规律的充值,但服务器的使用却一直未受影响而断过) 首先我第一反应是看我总共实际花了多少钱。 我的 vultr 是绑定 Paypal 作为付款方式,而 Paypal 中绑定了两张银行卡,一张储蓄卡,一张信用卡,在查阅了银行卡关于 paypal 的消费记录后统计如下 然后我试着从 vultr 账单中与之响应对账 的确找到四笔是通过 paypal 消费的 现在证实了一点,我一共在 vultr 花费了 17.65 美元,折合人民币 123.6 元 那么接下来再通过这四笔明确的消费来反推其他账单记录的含义,发现一笔比较特殊的 计算得到 由此可见 vultr 是按小时计费,一开始承诺的每月 5 美元,指的是如果你用满一个月(744 个小时,31 天)为 5 美元,而使用就是指你的服务器开启着(记录中一开始有十几天没计费应该是我虽然开通了 vultr 并且也充了值,但是没建立服务器实例,或者说建立的实例没开启) 归根结底,当服务器开启,每个月还是相当于 5 美元的,这样再看账单可以清晰一点 那么更进一步,我回想到之前按照首页提示的奖励金额去关注了 vultr 的 twitter 账号,所以有了 11 月这三笔记录 这三笔很明显是系统审核我的行为后为我以信用账户(accout credit)的方式分别充值了 3 美元 至此,整体应该算是破案了,我们可以用类比的思想(把陌生的事物类比成熟悉的事物,以便理解)可以理解为,vultr 在开通账户的时候是需要先付款后消费,不存在试用(先免费用,再补交费用)的情况。 但是当开通账户并充值以后,它的收费方式是每月 1 号,结算上个月的消费实际情况,会给你账单记录中发送一枚发票(invoice),你使用 paypal 进行的主动充值也会有所记录。但是可以先消费,后缴费。具体体现就是你这个月使用的费用是下个月 1 号结算,如果到时候你的 vultr 账户余额不足,它就会从你绑定的支付方式(比如 paypal 或信用卡)中自动扣款。...

2017-11-28 12:38:01 · 1 分钟 · 145 字

使用分支备份hexo博客

使用一台电脑使用 hexo 创建博文、生成静态文件、发布,没毛病,但由于 hexo 在本地生成静态文件的模式,如果你换一台电脑呢?很明显你需要把原始电脑上的 hexo 文件夹拷贝到新电脑。这样带来的问题就是多台电脑上的 hexo 不能总保持同步,需要通过物理拷贝的方式,很不方便。 正文 实现方式可能有多种,但我看到的主流方式是通过在远端仓库添加分支来保存 hexo 原始文件来将你的整个博客工程交由 git 管理。 hexo 本身的确是通过 git 发布到远端的,也就是借助 hexo-deployer-git 这个 nodejs 模块,但其功能是将 hexo 发布目录(public)里的静态文件上传至远端仓库,因为远端仓库是通过 pages 服务直接访问仓库文件,需要保证仓库文件符合 web 可访问结构。 假如你把 hexo 原始工程目录上传到你的同名仓库来实现 pages 服务,是无法正常访问的。 那么我们可以再建一个仓库来管理 hexo 原始工程文件,但没必要,这里通过在原仓库上添加分支来保存 hexo 原始工程文件,达到管理的目的。 操作步骤 hexo 主目录默认有一个.gitignore 文件,暗示可以通过 git 管理 hexo 主目录 可以在 hexo 主目录通过 git bash here 唤出 git bash,然后 git 初始化 hexo 主目录 git init 这样 hexo 主目录会多一个隐藏目录.git 创建本地分支,与远端的分支对应 git checkout -b source 然后将 hexo 主目录的所有文件按照....

2017-11-17 17:39:36 · 1 分钟 · 176 字

Markdown语法学习整理

虽说 markdown 用了一段时间,但还未曾专门地阅读文档对其进行过相对系统的学习。刚才使用分割线时发现分割线下面的文字变成标题般字体,专门查了一波,发现还是有必要系统学习一下 md 语法,以节省日后使用时的查阅时间。 宗旨 易读易写 一份使用 markdown 格式撰写的文档理应可以直接以纯文本发布,也就意味着 markdown 的一系列标签语法对于纯文本来说应该是低浸入、无感知的,用户阅读不会因为增加了 md 标签而变得晦涩。 这点区别于 HTML 语言至少还需要掌握 HTML 编程语法,才能理解部分标签的使用规则。 灵感 markdown 最大灵感源自纯文本电子邮件的格式(可能人们对于纯文本的电子邮件格式觉得太过单调,于是通过添加一些小标记,来增加丰富的格式) 目标 成为一种适用于网络的书写语言 markdown 并非要取代 HTML,甚至也没有要和它相近。 相比 HTML,markdown 语法种类少,仅对应 HTML 标记的一小部分 让文档更容易读、写、随意改 易读的前提就是 md 的标记需要尽量的没有侵入感,比如一篇纯文本文档增加 md 标记后不会影响原始阅读感受 易写易改的要求则是 md 的语法标记需要同 HTML 一样“语义化”,能够见标知意 兼容 HTML 区块标签 一些 HTML 区块元素比如<div>、<table>、<pre>、<p>等,必须在其前后加上空行与其他内容隔开,并且开始标签与结束标签不能用制表符(Tab)或空格来进行缩进。 (下面实例的缩进实现方式是通过 HTML 的 pre 标签,使其内部的 markdown 语法失效) 比如这里的 HTML 标签如果我想要以标签的样子显示在屏幕上,那我其实需要在文本里通过 md 标记来编辑,类似使用 code 标签、转义字符(通过转义字符来“画出”尖括号,code 标签可以使其成为块状文本) 另外,markdown 生成器不会在 HTML 区块标签外加上不必要的<p>标签,区别于对于 HTML 文本进行编辑时,若你写了大段内容而未加任何标签的话,HTML 生成器会为你在内容前后加上<p>标签...

2017-11-17 10:09:16 · 1 分钟 · 195 字

git学习总结

对于 Git 学习的一些整理,包含常用命令整理 个人觉得,对于一些开源工具,最好的学习资源还是其官网,我们就先来分析一波 Git 究竟是做什么的。 概念解析 git 官网的定义是:Git 是一种免费并且开源的分布式版本控制系统,被设计用来快速高效地处理堆积成大工程的每一块小部分。(个人翻译,不喜勿喷) Git 简单易用、占用空间小并且性能优越。它远超过一些伴有类似廉价的本地分支、方便的阶段区域和多工作流特点的配置管理工具(SCM,Software Configuration Management),比如 SVN、CVS、Perforce 和 ClearCase 这些。 Git 允许同一组下的人们同一时刻在相同的文档上工作(通常是代码),并且不会踩到其他人的脚趾(形容两个人同时在相同的文档上工作也不会发生冲突) 特性 小而快速(Small and Fast) 分布式(Distributed,这也是它比 SVN 优势明显的地方) 数据保证(Data Assurance) 分阶段区域(Staging Area) 免费并开源(Free and Open Source) 教程 初级教程:Try Git 高级教程:gitreal 官方书籍:Pro Git 使用步骤(包含常见命令) 1.初始化 git init init 命令会创建一系列 git 结构的文件 仅对一个制定目录创建 git 结构时使用,用于将某个目录交给 git 管理 2.查看 git 状态 git status 可在任何时间阶段使用, 以查看当前 git 管理下的文件状态 3.将文件交予 git 管理 git add filename 对于在 git init 后的目录里的每一个文件都有 tracked 和 untracked 两种状态,也就是是否被 git 追溯(管理)...

2017-11-17 09:54:33 · 2 分钟 · 330 字

关于centos的iptables以及firewalld的总结

centos 内置一个非常强劲的防火墙,统称为 iptables,实际原理是 iptables 是用户空间的模块,在内核中存在一个 netfilter 核心模块用于实现 iptables 中设置的规则,进行底层的实际过滤。 iptables 关键字 IP 地址 协议(TCP、UDP、ICMP) 端口 原理 iptables 将规则放入缺省规则链(INPUT、FORWARD、OUTPUT),所有流量(IP 封包)会被相关的规则链检查,根据规则处理每个封包(ACCEPT/REJECT),这些动作称为目标(target) INPUT:以主机为目的地的封包 FORWARD:封包的目的地和来源地都不是主机,途经主机(由其选路),比如主机是路由器,这条规则链将被应用 OUTPUT:源自主机的封包 每个封包会逐一匹配每条规则,若符合某一条规则,响应动作将被执行(ACCEPT/REJECT),一旦吻合一条规则,则不再被其他规则检查。若所有规则都不匹配,将会执行这条规则链的缺省动作(即括号内的缺省策略) 使用方式 白名单方式:即规则链缺省规则设为 REJECT,仅对符合某些条件的封包进行放行,例如:bittorrent、FTP 服务器、网页服务器、Samba 文件服务器 黑名单方式:规则链缺省策略设置为 ACCEPT,对需要拦截的封包做拦截 REJECT 一般白名单用于 INPUT 规则链,用于控制目的地为主机的封包,黑名单用于 OUTPUT 规则链,用于控制由主机流出的封包 使用 iptables 需要 root 用户操作 iptables 是缺省安装在 centos5.x 及 6.x 上,而 centos7.x 使用 firewalld 取代之 先使用 rpm -q iptables 查看 iptables 是否安装在系统上 lsmod | grep ip_table 检查 iptables 模块是否被装入, 当 iptables 模块被装入后可通过 iptables -L 查看活动规则...

2017-11-16 15:57:50 · 2 分钟 · 225 字

关于StackExchange和Quora的区别

今天在查问题的时候偶然进了一篇 StackExchange 的帖子,无论是站点名字还是首页界面,第一反应都是:StackOverFlow? 查阅相关说明之后了解了二者的关系,StackExchange 是在 StackOverFlow 成功推出以后,在其基础上将仅仅讨论编程问题的网站拓展成话题更丰富的论坛。 当更加深入了解二者关系之余发现一篇关于对比 StackExchange 和 Quora 二者区别的帖子写得很清楚,特将其翻译如下: 正文 简短版本: StackExchange 是你的助教 Quora 是你的酒保 Quora 是你认识的那个足迹遍布很多角落,品尝过城市每一家餐厅的人 StackExchange 是一个受过专业训练的专业帮助者 StackExchange 是一个指导手册(详细,包含有用的例子) Quora 是一个著名的在其演讲后回答问题的知识分子 详细版本: 想真正理解这二者,你需要从 the lens of purpose(目标透镜)看这个问题,从那里你能了解到一个专门的推送(see pull request at github?),它会从本质上讲清楚二者的区别。你会知道以下绝非偶然——Quora 不想成为 StackExchange,StackExchange 也不想成为 Quora,并且它们按照各自的方式建设以促进它们各自的目的。 正如 Manish 所述,Quora 是关于“消费”,但它也关乎好奇。也就是,我在阅读问题的时候更多的是被动的,大多时候我可能会在 Quora 的邮件中看到一个有趣的问题之后发现自己想要的。我会阅读问题的答案(或者不止几个),然后查看站点上推荐给我的相关问题,同时我也会阅读它们。这些问题中很少数曾“逼迫”我去寻找一个答案,但我就是充满好奇并且想要了解更多。 StackExchange 不同于其他在于其基于目的或者基于问题。我来到 StackExchange 大多情况是通过搜索引擎,因为我在处理某些事情上遇到问题并且需要答案。它绝大多数时候当然充当了一个技术支持,经常可以处理……(未完待续) 尾声 通篇下来个人觉得充满了蹩脚的翻译,这篇文章看起来大体可以理解作者的意思,但落实翻译对于我而言是不小的挑战。 个人比拟 国外网站 对应 国内网站 StackExchange <—> 暂无 Quora <—> 知乎 StackOverFlow <—> SegamentFault 相关链接 原文链接

2017-11-14 14:15:57 · 1 分钟 · 67 字

关于负载均衡的理解小结

均衡,存乎万物之间 负载均衡(Load Balance)是指将请求均匀分摊到多个操作单元上执行,关键在于均匀 本来在学习过反向代理这个概念以后以为负载均衡就是反向代理在服务端将来自客户端短时大量的访问请求做分发,将其分配到多台提供相同服务的服务器上。 看了负载均衡以后发现其实负载均衡是一个很宏观的概念,上述的理解存在一定偏差。 负载均衡旨在将特定的业务分担给多个服务器或网络设备,从而提高业务处理能力,保证业务的高可用性。 (负载均衡用于缓解极大量的访问请求,所以下面的场景都基于同时来自客户端大量的访问请求) 首先,我上面的理解在实际的负载均衡中其实表述的是【DNS 层】(客户端->反向代理层)的负载均衡,这一层的负载均衡由 DNS 服务器实现。 具体也就是当用户通过网站域名访问服务时,为了负载均衡,同一域名会配置多个解析 IP,每当 DNS 解析请求来访问 DNS 服务器时,它会轮询这些 IP,并保证每个 IP 的解析概率相同(均匀),这些 IP 就是 nginx 的外网 IP。 然后拿到某台 nginx 的 IP 也就结束了第一层的负载均衡 接下来,来到【反向代理层—>站点层】,这一层的负载均衡通过 nginx 的配置实现,策略有很多种:比如轮询、IP 哈希、URL 哈希、权重等 请求轮询:类似 DNS 轮询,请求依次被路由到每一个 web 服务器 最少连接路由:将请求路由到连接数最少的 web 服务器 IP 哈希:通过客户端 IP 的哈希值来路由到某一个 web 服务器(只要用户 IP 分布均匀,理论上路由的路径就是均匀的),这样同一个用户的请求会固定路由到固定的某一台 web 服务器上,该策略适合有状态服务,比如 session(但不建议这么做,因为站点层无状态是分布式架构设计的基本原则之一,session 最好放在数据层存储) 然后是【站点层->服务层】的负载均衡,该层通过服务连接池实现 上游连接池与下游服务建立多个连接,每次请求会“随机”选取连接访问下游服务 最后是【数据层】负载均衡 当数据量十分庞大的时候,数据层(db,cache)可能会进行数据的水平切分,于是该层的负载均衡包含“数据均衡”和“请求均衡”两部分 数据均衡指:水平切分后的每个服务(db,cache),彼此之间数据量均匀 请求均衡指:水平切分后的每个服务(db,cache),彼此之间请求量均匀 常见水平切分法如下: 按照数据范围切分:每个数据服务存储一定范围内的数据 DataServiceA:存储 uid 为[1-1kw)内的数据 DataServiceB:存储 uid 为[1kw-2kw)内的数据 优点:...

2017-11-09 17:37:16 · 1 分钟 · 112 字

关于职业规划

最近几天开发任务不甚紧张,每天可能一部分是在读博客或者写博客。在此过程中,突然想给自己炖一锅鸡汤醒醒脑。 作为一个软件工程毕业的人,或许更宏观的讲,作为一个计算机专业毕业的人,该怎么规划自己的职业生涯呢? (这里不讨论想转行的同学们,我很幸运当初坚持了自己的选择和判断,由于兴趣,入行了计算机,如今应该称呼为“互联网”领域) 过程在我看来是先易后难的 第一阶段 刚毕业的两三年,甚至五年,可能都是知识储备期,也就是技术积淀期。当然,打牢基础并不意味着沉迷基础,走走停停,及时看清楚技术风向标,是避免徒劳无功的基本意识。 在打牢基础的这几年应该做什么?或者说应该培养哪些能力 专业基础自然不用说,那是最基本的敲门砖,可能在学生时代,每个人的专业能力还都参差不齐,但步入职场后,对于每个从事技术工作的人,在技术基础方面的要求都是“一视同仁”的,也就是对于从事各个不同技术方向的人,你的技术栈都应该是完整的。为什么说这些是最基本的呢,因为这些东西大多是“死”的,也就是不管量有多少,甚至还在不断增加,但它的本质几乎不会发生质的变化,所以关乎技术的东西,你可以从学校、书籍或者人那里都可以习得,而后面要讲的第二阶段的技能可能不是单纯靠“学习”便可拥有的。 那么能力方面应该涉及哪些呢?个人总结如下(其实在不管大型还是初创的各个互联网公司招聘中也能经常看到这些字眼): 学习能力:首屈一指必然是学习的能力,因为这一点决定你“可拓展性”有多强,这里的学习能力指的是活学活用以及持续学习的能力。假如你是以初高中某些死记硬背或者应试手段的学习方法,我不敢保证那样的收益如何,因为我不曾有过以那样的方式的学习经历。另外就是持续学习的概念,这种需求其实是由时代滋生的,因为如今的时代决定了你很难(我没有说“不可能”的字眼)以固定的知识量驾驭你的整个职业生涯。 综合上面两种学习的能力其实也就自然带来你上手新事物的能力,比如公司派你去负责完成一项新的任务,使用的是一项你从未接触过的技术,那么此时如果你是拥有学习的能力,而不是仅仅拥有定量的知识,那么任何新事物你自然都能搞定。 理解能力:这是一个输入+分析的过程(Input & Process),理工一点的说法类似计算机的核心(CPU)处理任务方式。理解能力决定你在学习一项新事物时的效率,比如如果你对一个事物在最初认识的时候发生了偏差,那可能你用的劲越多,就越偏离理解它的正规。另外逻辑思维也在此体现出重要的作用,可能单纯的理性思维并不能帮助你快速地认识到新事物的本质,有时候可能还需要一些感性思维,Maybe 想象力.etc 沟通能力:这是一个输出的过程(Output & Translate),有时候单纯一味地输入未必可以发挥你所掌握知识的最大价值,技术需要分享,而交流就是一个有效媒介。但是有时候知识的传递在一些糟糕的表达后会变得晦涩难懂,所以良好的表达能力才会成为知识传播的有效大使。另外,有效的沟通势必带来 1+1>2 的收益,这样既节省时间又提高效率的多赢结果是大家都希望看到的。 第二阶段 这些技能大多基于经验主义,并且没有标准答案 判断力:“错与对”、“进与退”、“黑与白”(太极思想,黑中有白,白中有黑)的判断是永恒的难题(突然想到明天即将上映“马爸爸”的《攻守道》) 趋势/形势判断:趋势的判断往往决定你路程的远近,这东西可大可小,小在一笔小额的投资,大在一个集团的定位,如果仅有埋头苦干的踏实,而没有远瞻未来的判断,想必很难成为一位成功的管理者。而形势的判断其实就是一句“识时务者为俊杰”,何时放手一搏,主动出击,何时及时止损,这里的学问也是需要经验的不断积累来沉淀所得。 决策能力:如果你进行统计,其实我们每一天的所有行为串起来就是一颗巨大的决策树,每一个分支的两种选择都会带来不同的结果,而如此累积,将会因为每一步的不同而带来巨大差异的结果,这也就是所谓世界上没有两片相同的叶子,两个人尽管处于相同的环境,接收相同的知识,完成相同的任务,也会在日积月累的微小差异中变成两个独一无二的个体。 能否做出正确的决策,能否果断地做出决策,能否预知不同决策带来的结果,能否对结果负责,这一点其实在 AlphaGo 与人类围棋对决中就已经证明了计算机在决策方面已经掌握非常强大的能力,人类如果不增强自己的优势,可能等待你的只是“智能危机”。 前面三项能力或多或少都和选择有关,这也是为什么讲“有时候,选择比努力更重要” 是否注重细节:每个领域都会有大量的同类竞争,能够另辟蹊径的毕竟是少数,那么如何在“大家都差不多的”的情况下脱颖而出,细节方面至关重要 能否抵抗诱惑:新手大多急于求成,急功近利,而老手则懂得放长线钓大鱼 这些能力没有人能教的了你,同时也是决定你能否成为一个拥有独立完整人格的个体。 后续 未来毕竟还是很难预知的,所以我也不想给自己太远的未来做太过具体的规划,每个人都有自己的想法和规划,我的观点不一定适用别人,所以本篇博文也仅仅是一篇与自己灵魂的对话,仅此而已。

2017-11-09 09:55:14 · 1 分钟 · 34 字

使用hexo搭建个人博客教程

用了一段时间的 hexo,本着“授人以鱼,不如授人以渔”的理念,决定整理一篇 hexo 使用教程,分享大家。 hexo 是一种快速、简单并且强大的博客框架,你可以通过使用 markdown 或者其他语言撰写 post(帖子),然后 hexo 引擎将其生成静态网页文件(当然,官网的说法是“在数秒内生成伴有漂亮主题的静态文件”)并以博文的形式显现出来。 写在前面 本文定位于面向非专业人士角度撰写的科普式教程,有专业基础的人可跳过大多步骤,仅阅读标*部分 背景 应@JXY 邀,要我教他搭建个人博客,于是也就找了一个足够的理由来回顾一波如何使用 hexo 搭建个人博客。 既然给别人讲东西,那自然要先对讲的东西深入了解,不然就是误人子弟了。于是打开hexo 官网,发现!竟然!被!墙!了!好吧,后来发现是 9 点多被墙了一段时间(貌似是 hexo 使用的 CDN 服务 Cloudflare 被 block 了),介于避免日后再想参考官网文档时无法及时访问,索性这次就把官网的一些精华翻译下来,留作日后参考。 *核心步骤 先看官方给出的安装步骤 准备篇 首先你要做好准备掌握以下几项东西: git nodejs bash 命令 好吧,这样讲未免显得门槛略高,其实 hexo 是一种非常零门槛的工具,只要你想学,任何没有专业知识的人都能用起来,只要照着做就可以了 环境搭建篇 第一步:在电脑安装git(如果下载不了,可以通过我的网盘下载git) git 是一个伟大的版本控制软件,它的作用在于作为一个代码提交工具,将你编写的每一行代码(或文字)存放到一个代码仓库,它在其中起到记录你每一次提交历史的作用,这样你就可以对自己的每一次提交历史有直观的查看,并且可以对比不同版本之间的区别,还可以回退到某一个提交历史节点,还有 balabala 很多好处。 第二步:安装 nodejs 当你安装好了 git 以后,可以鼠标右键唤出 git 方式一 然后你就可以很方便的安装 nodejs 了,通过如下命令先安装 nvm(此方式适用于专业人士,非专业人士请参考后面下载安装包的方式二) curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash nvm 是 nodejs version manager,nodejs 版本管理器,用以在机器上安装并维护多个 node 的版本...

2017-11-08 10:25:17 · 2 分钟 · 369 字

关于反向代理的整理

之前一直对反向代理这个概念理解的很模糊,网上参阅了很多解释,看完也是觉得不够信服,相比较而言觉得解释的还算良好的是知乎上看到的一个回答,但看了之后也仅限于“当时理解,过后就忘”,于是今天再次在 stackoverflow 看到的解释版本,特此翻译整理,留作备忘。 原文链接:https://stackoverflow.com/questions/224664/difference-between-proxy-server-and-reverse-proxy-server/366212#366212 如果当你访问不了这个链接的时候,也就说明,GFW 限制了大陆网络内的主机访问 stackoverflow 的网站内容,此时你即需要通过代理服务器来作为你的代理,帮你取拿到远端 stackoverflow 网站上的内容取回给你,这就是正向代理的使用实例。 而反向代理其实更常见,因为它充斥在我们每一天的网上冲浪之中,只不过你意识不到罢了(注意!这也就是正向代理和反向代理很大的特征区别之一:正向代理需要你去寻得一个代理来帮助你访问你访问不了的服务器资源,而反向代理是服务器端使用的代理,来处理你提交的访问请求,所以作为客户端的你是意识不到代理的存在的)。 比如你通过浏览器访问百度网搜索一个条目,或者直接在地址栏输入 stackoverflow.com,然而这个行为在互联网中有太多用户在做,所以百度或者 stackoverflow 的服务器不一定能够驾驭这么大的访问量,此时他们可能会把相同的服务部署在 N 多台服务器节点上,然后你其实访问到的是那些提供反向代理的服务器,反向代理服务器将大量的请求做了负载均衡处理,再把这些请求均衡合理地分配到那些提供相同服务的不同服务器节点上,这就是反向代理的实例。 接下来是本人对于 stackoverflow 上精彩回答的翻译,如有不准确之处请指正 前面的回答都很准确,但可能太过于精简了。我会试着增加一些例子。 首先,“代理”这个词描述了某个人或者某个事物扮演着代表另一个人的角色。在计算机领域,我们讨论的即是一台服务器扮演着代表另一台计算机的角色。为了保证观点可达性(即观点可以被很容易的理解)这一目的(这句感觉翻译的不太好),我会限制我的讨论仅限于“web 代理”,然而“代理”这一思想其实不仅限于 web 网站。 正向代理 大多数关于 web 代理的讨论都指的是"正向代理"(这句感觉翻译得不甚准确)。这种情况下的代理事件其实就是“正向代理”代表请求者从另一个 web 站点取得数据。 举个栗子,我会列举三台接入互联网的计算机。 X = 你的计算机,或者说互联中的“客户机” Y = 代理站点,proxy.example.org Z = 你想要访问的网站,www.example.net 通常,你可能是类似 X –> Z 这样的直连。 然而,在一些场景下,Y –> Z 来代表 X(去访问 Z)更好,链条如下:X –> Y –> Z 为什么 X 需要使用代理服务器的原因: X 无法直接访问到 Z: a)在 X 的互联网连接中某个拥有管理权限的人决定拦截所有 X 到 Z 站点的访问(比如 GFW : ) )...

2017-11-07 16:41:24 · 1 分钟 · 196 字

关于matlab使用冒号定义矩阵的小栗子

冒号是 MATLAT 中最有用的操作符之一。它用于创建向量,下标数组,并为迭代指定。 背景 怎么解释?作为初学者可能一下子看不懂,但是研究后你会发现,作为老手,你也不应该看懂,因为,这是个印刷错误! 借此学习一下 MATLAB 的冒号符和矩阵定义 冒号符( :) 创建行向量 包含从 1 到 10 的整数行向量 octave:2> 1:10 ans = 1 2 3 4 5 6 7 8 9 10 指定增量值 octave:3> 100:-5:50 ans = 100 95 90 85 80 75 70 65 60 55 50 one more 栗子 octave:4> 0:pi/8:pi ans = Columns 1 through 7: 0.00000 0.39270 0.78540 1.17810 1.57080 1.96350 2.35619 Columns 8 and 9: 2.74889 3....

2017-11-01 09:48:04 · 2 分钟 · 351 字

关于SQL性能评估的一些分析

继《关于 mysql 中 max 函数和 groupby 联合使用的坑》后进一步关于 SQL 性能的探究 类型 解释 id select 查询的序列号 select_type select 查询的类型,主要是区别普通查询和联合查询、子查询之类的复杂查询 table 输出的行所引用的表 type 联合查询所使用的类型 possible_keys MySQL 能使用哪个索引在该表中找到行 key MySQL 实际决定使用的键 key_len MySQL 决定使用的键长 ref 哪个字段或常数与 key 一起被使用 rows mysql 要遍历多少数据才能找到,在 innodb 上是不准确的 Extra - 实例解释 mysql> desc t3; +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | other | varchar(255) | YES | | NULL | | +-------+--------------+------+-----+---------+----------------+ 2 rows in set mysql> select * from (select * from (select * from t3 where id = 3952602) a) b; +---------+-------+ | id | other | +---------+-------+ | 3952602 | sth | +---------+-------+ 1 row in set mysql> explain select * from (select * from (select * from t3 where id = 3952602) a) b; +----+-------------+------------+--------+-------------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+--------+-------------------+---------+---------+-------+------+-------+ | 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | NULL | | 2 | DERIVED | <derived3> | system | NULL | NULL | NULL | NULL | 1 | NULL | | 3 | DERIVED | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | const | 1 | NULL | +----+-------------+------------+--------+-------------------+---------+---------+-------+------+-------+ 3 rows in set mysql> show index from t3; +-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | t3 | 0 | PRIMARY | 1 | id | A | 1 | NULL | NULL | | BTREE | | | | t3 | 1 | idx_t3_id | 1 | id | A | 1 | NULL | NULL | | BTREE | | | +-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 2 rows in set id 从里往外执行,从 id 为 3 往上执行...

2017-10-31 22:44:35 · 9 分钟 · 1801 字

关于mysql中max函数和groupby联合使用的坑

关于朋友随手抛出的一段 SQL,发现 MySQL 中关于 max()和 group by 联合使用中的一个坑,特此整理。 YH:老铁们,这段 hql 对不对啊 我扫了一眼,总觉得看着别扭,自己试着去掉字符串拼接,还原出 SQL 来看,依然感觉不对,然后自己试着写了查询,在本地建个表,造了些数据,用简化后的 SQL 做测试时, 当我定睛检查以下这句 SQL select predictId, max(evaluateDate) evalDate, productId from productcashpredict group by productId; 抛出一个疑问,MySQL 是从后往前执行,先分组再求分组结果中 evaluateDate 最大的记录呢?还是先找出 evaluateDate 的最大记录,再分组呢? 网上查了查,发现,都不是!这里有个坑!如果直接这么结合 max 和 group by 使用,查出的结果,除了求 max 的字段和分组条件 productId 字段,其他字段的值都是错的! 首先我在本地验证了一下是不是的确如此 desc productcashpredict; predictId int(11) NO PRI auto_increment evaluateDate datetime YES on update CURRENT_TIMESTAMP other varchar(255) YES productId int(11) YES select * from productcashpredict +-----------+---------------------+-------+-----------+ | predictId | evaluateDate | other | productId | +-----------+---------------------+-------+-----------+ | 1 | 2017-10-31 18:14:37 | NULL | 10001 | | 2 | 2017-10-31 18:14:45 | NULL | 10002 | | 3 | 2017-10-31 18:14:59 | NULL | 10002 | | 4 | 2017-10-31 18:15:09 | NULL | 10003 | | 5 | 2017-10-31 18:15:22 | NULL | 10001 | +-----------+---------------------+-------+-----------+ select predictId, max(evaluateDate) evalDate, productId from productcashpredict group by productId; +-----------+---------------------+-----------+ | predictId | evalDate | productId | +-----------+---------------------+-----------+ | 1 | 2017-10-31 18:15:22 | 10001 | | 2 | 2017-10-31 18:14:59 | 10002 | | 4 | 2017-10-31 18:15:09 | 10003 | +-----------+---------------------+-----------+ 直接这样查的确是错的,看 predictId 可以看出...

2017-10-31 20:50:43 · 5 分钟 · 1035 字

从谷歌"名猿"Addy Osmani一行代码中学到的东西

谷歌某大佬通过一行知识量包含极丰富的 js 代码实现了一个魔法小功能:给页面所有元素加一个彩色外边框 [].forEach.call($$("*"), function (a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); }); 单行形式: [].forEach.call($$("*"), function (a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); }); 将其贴到 chrome 的 console 中即可看到效果 代码解析 $$("*"); document.querySelectorAll("*"); document.all; 以上三种写法是相同效果,都相当于通过选择器的方式获取页面所有元素。第三种是较不规范的方式,不建议使用。$$是现代浏览器API的一部分,比如$$(‘a’)可以获取页面所有的 a 标签元素 接下来,通过上面选择器获取到的是一个 NodeList,是一种类似于数组 Array,但它并未实现很多 Array 的接口,所以不能使用$$(’*’).forEach 来遍历结果,类似的还有 arguments,也是类似于 Array,但并不是数组 这时需要通过 call()或者 apply()可以使得非数组对象来调用数组的方法 [].forEach.call($$("*"), function (e) {}); 以上即实现了遍历页面的每一个元素,并可以将获得的非数组元素使用数组的遍历方法来取到每一个元素 e a.style.outline = "1px solid #" + color; outline 是 CSS 的一个属性,它是在 CSS 盒模型以外,所以它不会影响元素的 size 以及元素在 larout 中的 position...

2017-10-17 16:45:17 · 1 分钟 · 130 字

atom实现html实时预览

如何使用 atom 编辑器实现 html 实时预览 atom 自带 markdown 实时预览插件,但当我想用 atom 进行进端开发并取代 webstorm 这样的收费 IDE 时,我发现基于文件进行操作的编辑器 atom 只能高亮显示 html、js 这样的文件,但不能实时显示进行调试,很不方便。 于是上网查,结果都是很简略的方法,作为刚开始上手 atom 的新手,一时不理解,终于经过自己的折腾成功使用 特此记录,以便为新手提供方便,节省这些不必要的查询时间。 1、搜索插件 2、安装插件 3、修改快捷键 atom-html-preview 初始快捷键为 ctrl+p,于 atom 已有快捷键冲突,修改为 ctrl+F12,如下 点击 File->Settings->KeyBindings->your keymap file 超链接->在末尾添加 'atom-text-editor': 'ctrl-F12':'atom-html-preview:toggle'

2017-10-16 19:00:44 · 1 分钟 · 39 字