姜蜀黍的记事本


  • 首页

  • 归档

《亿级流量网站架构核心技术》学习笔记 - 队列术

发表于 2017-05-31 | 分类于 亿级流量网站核心技术学习笔记
| 字数统计: 1,299

应用场景

  • 异步处理:当用户注册成功后,需要发送注册成功邮件、新用户积分、优惠券等;缓存过期时,先返回过期数据,然后异步更新缓存,异步写日志等。通过异步处理,可以提升主流程响应速度,而非主流程或非重要处理可以集中处理

  • 系统解耦:当用户成功支付完成订单后,需要通知生产配货系统,发票系统、库存系统、推荐系统、搜索系统等进行业务处理,而未来需要支持哪些业务是不知道的,并且这些业务不需要实时处理、不需要强一致,只需要报账最终一致性即可

  • 数据同步:如果想把MySQL变更的数据同步到redis,或者将MySQL的数据同步到Mongodb,或者让机房之间的数据同步,或者主从数据同步等,此时可以考虑databus、canal、otter等。使用数据总线队列进行数据同步的好处是可以保障数据修改的有序性

  • 流量削峰:系统瓶颈一般在数据库上,比如扣减库存、下单等。此时可以考虑使用队列将变更请求暂时放入队列,通过缓存+队列的暂存的方式将数据库流量削峰。同样对于秒杀系统,下单服务会是该系统的瓶颈,此时可以使用队列进行排队和限流,从而保护下单服务

    阅读全文 »

Java虚拟机知识点(1)-内存分区

发表于 2017-03-21 | 分类于 Java
| 字数统计: 1,988

JVM主要结构

JVM结构主要由4部分组成:

  • 类加载器
  • 执行引擎
  • 内存区
  • 本地方法调用
      类加载器用于在JVM启动时或者在类运行时将需要的class加载到JVM中,每个被JVM装载的类型都有一个对应的java.lang.Class类的实例来表示该类型,该实例可以唯一表示被JVM装载的clas类,要求这个实例和其他类的实例一样都存放在java堆中
      执行引擎的作用就是解析JVM字节码指令,得到执行结果。在《Java虚拟机规范》中详细定义了执行引擎遇到每条字节码指令时应该处理什么,并且应该得到什么结果。但是并没有规定执行引擎应该采用何种方式处理而得到这个结果。Java的一个县城第一营了一个执行引擎实例,那么在一个JVM实例中就会同时又多个执行引擎在工作,这些执行引擎实例有的在执行用户程序,有的在执行JVM内部的程序
阅读全文 »

JavaWeb编码详解

发表于 2017-03-17 | 分类于 Java
| 字数统计: 1,083

GB2312、GBK、UTF-16、UTF-8编码比较

  对于中文字符,使用GB2312、GBK、UTF-16、UTF-8均能对其进行处理。但是GBK的范围更大,他能处理所有汉字字符,所以讲GB2312与GBK进行对比,应该选择GBK。UTF-16与UTF-8都是处理Unicode编码,他们的编码规则不太相同。相对来说,UTF-16的编码效率较高,从字符到字节的相互转换更加简单,进行字符串操作也更好,它适合在本地和内存之间使用,但是它不适合在网络之间传输,因为网络传输容易损坏字节流,一旦字节流损坏就很难恢复,所以相比较而言URF-8更适合网络传输,UTF-8对ASCII字符采用单字节存储,另外单个字符损坏也不会影响后面的其他字符,在编码效率上结余GBL和UTF-16之间,所以UTF-8在编码效率和编码安全性上做了平衡,是理想的中文编码方式。

阅读全文 »

JavaScript详细教程(8) - JavaScript中的面向对象

发表于 2016-11-22 | 分类于 JavaScript
| 字数统计: 1,137

利用JavaScript实现一个集合类

集合(set)是一种数据结构,用以表示非重复值的无序集合,集合的基础方法包括添加值、检测值是否在集合中,以下代码将实现一个通用的set集合类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
function set(){
this.values = {}; //集合数据保存在对象的属性里
this.n = 0; //集合中值得个数
this.add.apply(this,arguments); //将所有参数都添加进这个集合里
}
//在函数原型对象中定义将所有参数添加进集合的函数
set.prototype.add = function(){
for(var i = 0 ; i < arguments.length; i++){
var val = arguments[i];
var str = Set.v2s(val);
if(!this.values.hasOwnProperty(str)){
this.values[str] = val;
this.n++;
}
}
return this;
};
//如何集合包含这个值,则返回true,否则,返回false
Set.prototype.contains = function(value){
return this.values.hasOwnProperty(Set.v2s(value));
};
//返回集合的大小
Set.prototype.size=function(){
return this.n;
}
//遍历集合中的所有元素,在指定的上下文调用f
Set.prototype.foreach = function(f, context){
for(var s in this.values){
if(this.values.hasOwnProperty(s)){
f.call(context, this.values[s])
}
}
};
//这是一个内部函数,用以将任意JavaScript值和唯一的字符串对应起来
set._v2s = function(val){
switch(val){
case undefined:
return 'u';
case null:
return 'n';
case true:
return 't';
case false:
return 'f';
default: switch(typeof val){
case 'number': return '#' + val;
case 'string': return '"' + val;
default:return '@' + obejctId(val);
}
}
//对任意对象来说,都会返回一个字符串
//针对不同的对象,这个函数会返回不同的字符串
//对于同一个对象多次调用,总是返回相同的字符串
//为了做到这一点,它给o创建了一个属性,在ES5中,这个属性是不可枚举且是只读的
function objectId(o){
var prop = "|**obejctId**|";
if(!o.hasOwnProperty(prop))
o[prop] = Set._v2s.next++;
return o[prop];
}
}
Set._v2s.next = 100;

阅读全文 »

JavaScript详细教程(7) - JavaScript中的类

发表于 2016-11-18 | 分类于 JavaScript
| 字数统计: 2,824

在JavaScript中,类的实现是基于原型集成机制的。如果两个对象实例都是从同一个原型对象上继承属性,我们说他们是同一个类的实例。JavaScript类的一个重要的特性就是“动态可继承”

类与原型

在JavaScript中,类的所有实例对象都从同一个原型对象上继承属性。因此原型对象是类的核心,通常是通过定义一个函数来创建并初始化新对象,下面代码中inherit()函数将返回一个新创建的对象,新对象继承自inherit函数中指定的原型对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//inherit()函数返回了一个继承自原型对象p的属性的新对象
//这里使用ECMAScript5中的Object.create()函数(如果存在的话)
//如果不存在Obejct.create(),则退化使用ECMAScript3支持的方式
function inherit(p){
if(p == null){
throw TypeError();
}
//如果支持ECMAScript5的Obejct.create语法
//则直接用Obejct.create()生成一个对象并将其原型属性设置为
if(Object.create){
return Object.create(p);
}
//进一步检查传入参数p的类型
var t = typeof p;
if(t !== "object" && t != "function"){
throw TypeError();
}
//声明一个空构造函数f
function f(){};
//将f的原型属性设置为p
f.prototype = p;
return new f();
}
function range(from, to){
var r = inherit(range.methods);
r.from = from;
r.to = to;
return r;
}
range.methods = {
//此函数用于判断参数x是否在范围内,如果在范围内则返回true;否则返回false
//这个方法可以比较数字范围,也可以比较字符串和日期范围
includes:function(x){
return this.from <= x && x <= this.to;
},
//对于范围内的每个整数都调用一次f
//这个方法只可用于数字范围确定
foreach: function(f){
for(var x = Math.ceil(this.from); x <= this.to; x++){
f(x)
}
},
toString: function(){
}
}
var f = range(1, 3);
r.includes(2) //=> true 2在这个范围内
r.foreach(console.log) //输出1, 2, 3

我们注意到range()函数定义了一个属性Range.methods,用以快捷地存放定义类的原型对象,把原型对象挂在函数上从语法上来讲没什么问题,但是这不是惯用做法

阅读全文 »

JavaScript详细教程(6) - 函数式编程

发表于 2016-11-06 | 分类于 JavaScript
| 字数统计: 552

JavaScript不是函数式编程语言,但在JavaScript中可以像操控对象一样操控函数,也就说可以在JavaScript中应用函数式编程技术。

使用函数处理数组

假设有一个数组,数组元素都是数字,我们想要计算这些元素的平均值和标准差,若使用非函数式编程风格的话,代码会是下面的样子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var data = [1,1,3,5,5];
//求平均数就是将所有的元素累加后的值除以元素的个数
var total = 0;
for(var i = 0; i<data.length; i++){
total += data[i];
}
var mean = total/data.length;
//求标准差就是每个元素减去平均数之后偏差的平方然后求和
total = 0;
for(var i = 0; i< data.length; i++){
var deviation = data[i]-mean;
total += deviation * deviation;
}
var stddev = Math.sqrt(total/(data.length -1))

可以使用数组方法map()reduce()来实现同样的计算,代码显得极其简洁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var sum = function(x,y){
return x+y;
}
var squre = function(x, y){
return x*y;
}
var data = [1, 2, 3, 4, 5, 6];
//求平均数
var mean = data.reduce(sum)/data.length;
//将数组中的每个元素减去平均值然后返回新的数组
var deviations = data.map(function(x){return x-mean;});
//将返回的新数组调用map函数使求得每个元素的平方然后再返回一个新的数组
//然后再将重新返回的数组调用reduce函数使各元素值相加
var stddev = Math.sqrt(deviations.map(squre).reduce(sum)/(data.length -1));

高阶函数

高阶函数就是操作函数的函数,它接收一个或多个函数作为参数,并返回一个函数,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//这个高阶函数返回一个新的函数,这个新函数将他的实参传入f()
//并返回f的返回值的逻辑非
function not(f){
return function(){
var result = f.apply(this,arguments);
return result;
}
}
//判断x是否为偶数的函数
var even = function(x){
return x % 2 === 0;
};
//一个新函数,所做的事情和even()相反
var odd = not(even);
[1, 1, 3, 5, 5].every(odd); // => true:每个元素都是奇数;

上面的not()函数就是一个高阶函数,因为它接收一个函数作为参数,并返回一个新的函数。

JavaScript详细教程(5) - 函数

发表于 2016-10-29 | 分类于 JavaScript
| 字数统计: 4,178

一、调用函数

在JavaScript中有4种方式来调用JavaScript函数

  • 作为函数
  • 作为方法
  • 作为构造函数
  • 通过他们的call()和apply()方法间接调用

作为函数调用

根据es3和非严格的es5对函数调用的规定,调用上下文(this的值)是全局对象。在严格模式下,调用上下文则是undefined

以函数形式调用的函数通常不适用this关键字。不过,”this”可以用来判断当前是否是严格模式

阅读全文 »

JavaScript详细教程(4) - 数组

发表于 2016-10-27 | 分类于 JavaScript
| 字数统计: 1,326

数组是值的有序集合。每个值叫做一个元素,而每个元素的数组中有一个位置,以数字表示,称为索引

创建数组

使用数组直接量创建

1
var array = [1, 2, 3, 4];

调用构造函数创建

若在调用构造函数时没有传入参数,如下面代码所示:

1
new Array();

该方法创建一个没有任何元素的空数组,等同于数组直接量[]。若在调用时传入一个数值参数,则该参数指定了数组的长度。如下面代码所示:

1
new Array(5);

这种方式创建的数组没有存储值,甚至数组的索引属性“0”,“1”等还未定义。

阅读全文 »

JavaScript详细教程(3) - 对象

发表于 2016-10-23 | 分类于 JavaScript
| 字数统计: 2,509

JavaScript中对象大致可以分为三类:

  • 内置对象,是由ECMAScript规范定义的对象或类(构造函数)。例如:数组,函数,日期和正则表达式等
  • 宿主对象,是由JavaScript解释器所嵌入的宿主环境(比如Web浏览器)定义的,宿主对象可以当作内置对象看待
  • 自定义对象,是由运行中的JavaScript代码创建的对象

对象中的属性分为两类:

  • 自有属性,直接在对象中定义的属性
  • 继承属性,是在对象的原型对象中定义的属性
阅读全文 »

JavaScript详细教程(2) - 类型、值和变量

发表于 2016-10-18 | 分类于 JavaScript
| 字数统计: 927

JavaScript数据类型可以分为两类:原始类型和对象

原始类型

原始类型包括:数字、字符串和布尔值、null(空)、undefined(未定义)

对象

JavaScript语言核心已经预定义几种类型的对象。数组是一种特殊的对象,JavaScript为数组定义了专用的语法,使数组拥有一些和普通对象不同的行为特性。函数是另一种特殊的对象,具有与它相关联的可执行代码的对象,通过调用函数来运行可执行代码,并返回运算结果。果函数用来初始化一个新建对象,我们称之为构造函数。每个构造函数定义为一类对象,类可以看做是对象类型的子类型

除了数组类(Array)、函数类(Function),JavaScript定义了其他几种有用的类:

  1. 日期类(Date)定义了代表日期对象。
  2. 正则类(RegExp)定义了表示正则表达式的对象。
  3. 错误类(Error)定义了那些表示程序中运行时错误和语法错误的对象。
阅读全文 »
1234
© 2018 jiangCluster
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4