DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

数据库相关

索引的处理:

  • 内存映射文件

MongoDB, Cassandra, Riak等

  • 较小的索引集合,采用元索引或者bloom Filter进行一些优化

一旦内存数据足够多,比如达到MB,我们就对它们进行排序,而后将它们作为单个小的索引写入硬盘中。最后得到的是一个小的、由不变索引文件组成的年表。

  • 简单匹配算法(brute force)又叫做面向列(Column Oriented)

日志结构合并树,在HBase,Cassandra等不同地方应用。

将索引存储在内存中,或者利用诸如日志结构合并树(Log Structured Merge Tree)这样的写优化索引结构,绕开“随机写惩罚”(random-write penalty)。这是第三种方案为纯粹的简单匹配算法(Pure brute force)。

面向列是一种简单的理念,和行存储数据不同,通过列分割每一行,将数据追加到单个文件末尾。接着在每个单独的文件中存储每一列,一旦需要只需读取需要的列。
这样可以确保文件的含有相同的序列,即每个列文件的第N行含有相同的地址或者偏移量。这个很重要,在某一时刻读取多列,来服务一个单一的查询。意味着“连接(joining)”列速度飞快,倘若所有的列含有相同的序列,我们就能在一个紧凑的循环中这么做,此循环有很好缓存和CPU利用率。许多实现大量使用向量( vectorisation)进一步优化简单连接和过滤操作吞吐量。

诸如卡夫卡(Kafka)采用一个简单的、基于硬件的高效消息规范。消息可以简单地追加到文件的末尾,或者从预定的偏移量处读取。可以从某个偏移量读取消息,来来回回,你可以从上次结束的偏移量处读取。看得出是很不错的有序输入输出(IO)。

这和多数面向消息的中间件不同,JMS(Java消息服务)和AMQP(高级消息队列协议)说明文档需要额外的索引,来管理选择器和会话消息。这意味着它们结束某个行为的方式更像数据库,而非某个文件。著名的论述是1995年Jim Gray发表的队列就是数据库(Queue’s are Databases).

分布式数据库下的CAP(Consistency, Availability, Partition-Tolerance)

前端读服务

是不是借鉴机器人?

一些设计原则

  • 无状态
  • 数据闭环
    Hash Tag
  • 缓存银弹
  • 并发化
  • 降级开关
  1. 开关集中化管理:通过推送机制把开关推送到各个应用;
  2. 可降级的多级读服务:比如只读本地缓存、只读分布式缓存、或者只读一个默认的降级数据;
  3. 开关前置化:如架构是nginx—>tomcat,可以将开关前置到nginx接入层,在nginx层做开关,请求不打到后端应用。
  • 限流
  • 切流量
  • 其他

1、首先接入层读取本地proxy cache / local cache;

2、如果不命中,会读取分布式redis集群;

3、如果还不命中,会回源到tomcat,然后读取堆内cache;如果没有,则直接调用依赖业务获取数据;然后异步化写到redis集群;

nginx + lua

跟我学Nginx+Lua开发

控制抽象

函数值用做参数

1
2
3
4
5
def filesMatching(query: String,
matcher: (String, String) => Boolean) = {
for (file <- filesHere; if matcher(file.getName, query))
yield file
}

闭包,自由变量?

List的高阶函数exists 配合占位符

1
def containsOdd(nums: List[Int]) = nums.exists(_ % 2 == 1)

Curry化

curry化函数被应用于多个参数列表,

1
def first(x: Int) = (y: Int) => x+y
1
2
3
4
5
6
7
8
9
10
11
12
13
def withPrintWriter(file: File, op: PrintWriter => Unit) {
val writer = new PrintWriter(file)
try{
op(writer)
} finally {
writer.close()
}
}

withPrintWriter(
new File('date.txt'),
writer => writer.println(new java.util.Date)
)

使用大括号代替小括号包围参数列表,实现内建控制结构

叫名函数

组合和继承

elem(s:String): Element

抽象类,无法被实例化,

无参数方法,且仅通过读含有对象的方式访问可变状态

字段值在类初始化的时候被预计算,而方法调用在每次调用的时候都要计算。

scala定义不带参数也没有副作用的方法为无参数方法,省略空的括号,是鼓励的风格,另一方面,永远不要定义没有括号的带副作用的方法。

子类和超类

scala仅微定义准备了两个命令空间,值(字段,方法,包还有单例对象),类型(类和特质名)

多态和动态绑定

使用组合与继承

for循环中的until

1
for(i <- 0 until this.contents.length)

scala的层级

42为Int的实例,不能使用new Int

java中基本类型和引用类型的区别,

Any <- AnyVal, AnyRef, ScalaObject <- …

AnyRef定义了eq方法,它不能被重写,并且实现为引用相等。 通过eq 引用的相等比较它们的实例部分?那就是==代表为实例的相等?

scala.Null: 每个引用类型的子类,不兼容值类型

Scala.Nothing: 任何其他类型的子类,

特质 trait

混入”特质”,而不是继承它们

1
2
3
4
5
trait a {
def b = {

}
}

with 超类中混入特质,

类似带有方法的java接口?

特质不能有”类”参数,构造函数不允许有参数,

class extends trait 构造的时候,需要指明?

1
class R(val topLeft: Point, val rightLeft: Ponit) extends  

Ordered 用来compare 类似于comparator?

可堆叠改变特质?

更类似与切面,但切面也可继承超类以及相关?

with的次序很重要,一般,越靠近右侧,越先起作用,

多重继承?trait extends超类,使用super部分,线性化解释super的方式?

包和引用

1
2
import x.x
import x._
1
2
3
4
def showFruit(fruit: Fruit) {
import fruit._
println(name + "a " + color)
}
1
import Fruits.{Apple => a, Orange}

java允许外部类访问其内部类的私有成员

伴生对象?

样式类和模式匹配

case class 和 pattern matching

选择器 match {备选项}

match同switch的比较:

  • match始终以值为结果
  • 备选表达式永远不会掉到下一个case
  • 如果没有模式匹配,会抛出matchError

case _ => 通配

模式的种类:

  • 通配模式
  • 常量模式
  • 变量模式
  • 构造器模式
  • 元组模式
  • 类型模式
  • 变量绑定

模式防卫

模式重叠

模式部分,用来进行消息的处理?

基本类型

Byte Short Int Long Char String Float Double Boolean

管道符号放在字符串前,并且调用stripMargin方法。

符号文本 Symbol 可以是任何字母或数字的标识符 ‘<标识符>

Int类带有+方法,所以为(1).+(2)

操作符和方法,操作符部分,采用后缀操作符标注方式

对象的相等性 == !=

富包装器 max min abs round

函数式对象

1
2
3
4
class Rational(n: Int, d: Int) {
require(d !=0)
override def toString = n +"/" + d
}

自指向: this

从构造器,

字母数字标识符, 操作符标识符

隐式转换

1
implicit def intToRational(x: Int) = new Rational(x)

内建控制结构

几乎所有的 Scala 的控制结构都会产生某个值

1
2
3
var filename = 
if(!args.isEmpty) args(0)
else "default.txt"

for + 过滤

1
2
3
val filesHere = (new java.io.File(".")).listFiles
for (file <- filesHere if file.getName.endsWith(".scala"))
println(file)
1
2
3
4
5
for (
file <- filesHere
if file.isFile;
if file.getName.endsWith(".scala")
) println(file)

for{子语句} yield {循环体}

match表达式替代switch case

没有break和continue

变量范围,注意重名

函数与闭包

first-class function, 不仅可以定义函数和调用它们,还可以将他们变成值传递。

占位符语法 _

偏应用函数

1
val b = sum (1, _: Int, 3)

函数文本在运行时创建的函数值(对象)被称为闭包,closure。源自于通过“捕获”
自由变量的绑定对函数文本执行的“关闭”行动。

重复参数

1
2
def echo(args: String*) = 
for(arg<-args) println(arg)

尾递归部分

Scala把面向对象和函数式编程融合成一套,函数值就是对象,函数类型是能够被子类继承的类。

函数式编程有两种理念作为指导,第一种就是函数是第一类值,同整数或字符串,在同一地位。第二种主要的理念是,程序的操作符应该把输入值映射到输出值而不是就地修改数据,也就是更多的不可变的数据类型。也就是说方法不应有任何副作用: side effect。

好处: 兼容性,简洁性,高层级,静态类型的

类型推断:type inference

var val的区别:

  • val: 当你用val定义一个变量,那么这个变量就不能重新赋值,但它指向的对象却可以暗自改变
  • var: 表明为指令式的风格编程,

指令式 imperative风格编程,转化为 函数式 functional风格编程

伴生对象: companion object, apply

scala部分,操作符为右操作符,例如::,:::,list的add操作,没有append操作

scala部分,public是缺省的访问级别。

scala编译器可以将任何类型转换为Unit

1
2
3
4
5
class ChecksumAccumulator {
private var sum = 0
def add(b: Byte): Unit = sum+=b
def checksum(): Int = ~(sum & 0xFF) +1
}

分号的推断

scala比java更加面向对象,scala没有静态成员。替代品部分,采用单例对象,singleto object。每个单例对象,都被作为由一个静态变量指向的虚构类,

单例对象与某个类共享同一个名称,伴生对象,companion object. 孤立对象,standalone object.

1
2
3
4
5
6
object Summer {
def main(args: Array[String]) {
for (arg <- args)
println(arg + ":" + calculate(arg))
}
}

fsc(快速Scala编译器)的Scala编译器后台服务,创建本地的端口运行服务后台。

Application 特质,extends Application, 因为Application声明了带有合适签名的main方法,并由你的单例对象继承,使它可以像个scala程序使用。相关括号之间的代码呗收集进了单例对象的主构造器: primary constructor。 缺点:无法获取args,同时,jvm的线程模型局限