WebSocket 的鉴权授权方案

引子

WebSocket 是个好东西,为我们提供了便捷且实时的通讯能力。然而,对于 WebSocket 客户端的鉴权,协议的 RFC 是这么说的:

This protocol doesn’t prescribe any particular way that servers can
authenticate clients during the WebSocket handshake. The WebSocket
server can use any client authentication mechanism available to a
generic HTTP server,[……]

阅读全文

算法复杂度和大O表示法

概念

SICP算法复杂度是算法分析里的概念(对应到SICP里的增长阶),是衡量计算资源消耗数量(例如计算时间,存储器使用等)的指标。

算法的复杂度在理论上表示为一个函数:其定义域是输入数据的长度(通常考虑任意大的输入,没有上界),值域通常是执行步骤数量(时间复杂度)或者存储器位置数量(空间复杂度)。

这个函数形如:

R(n) = Θ(f(n)) 亦可记做 O(f(n))

f(n) 就是被度量的算法主体;算法的复杂度标记就是大O(Θ读做theta),这种记法称为大O表示法

常见复杂度级别

  • Θ(1) 常数级别
  • Θ(log(n)) 对数级别
  • Θ(n) 线性级别
  • [……]

阅读全文

八皇后问题的Julia实现

问题

八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?

尝试使用Julia实现一个回溯解:

julia-lang

实现

回溯法进行暴力查找:

很可惜,我的代码高亮插件不支持Julia的语法 :(

输出

Monad备忘录

最近需要补的东西较多,疏于打理关于Monad的学习笔记,所以赶在到公历新年前,先整理出一部分,以备忘:

是什么?

A monad is just a monoid in the category of endofunctors, what’s the problem?

单子 不过是一个自函子范畴上的半幺群

单子(monad,也译单体)是函数式编程中的一种抽象数据类型,其特别之处在于,它是用来表示计算而不是数据的。在以函数式风格编写的程序中,单子可以用来组织包含有序操作的过程,或者用来定义任意的控制流(比如处理并发、异常、延续)。

定义

单子的构造包括定义两个操作return和b[……]

阅读全文

爬虫的终极形态:nightmare

nightmare 是一个基于 electron 的自动化库(意思是说它自带浏览器),用于实现爬虫或自动化测试。相较于传统的爬虫框架(scrapy/pyspider),或者dom操作库(cheerio/jsdom),或者基于浏览器的自动化框架(selenium/phantomjs),他的优势在于提供了一个简洁有效 的编程模型。

来看官网给出的一个对比场景:

同样是实现一个向yahoo自动提交关键词并搜索的功能

1. PhantomJS实现

2. nightmare实现
[crayon-58afe89311[……]

阅读全文

实现一个Node.js版本的Consul SDK

Consul

Consul 是一个开源软件,用于实现分布式系统的服务发现与配置,内置如下功能:

  • 服务的注册和发现
  • 键值对存储
  • 健康检查
  • 多数据中心支持

Node-Consul

目前实现最为完备的 Consul 客户端是 node-consul,看看它的功能点:

  • ACL: 访问控制
  • Agent: 检查/服务注册
  • Health: 健康信息获取
  • Catalog: 目录列表
  • KV: 键值对存取
  • Event: 发送事件与列表
  • Query: 查询服务信息
  • Status: Raft一致性的状态信息

Too much,超出了需求范[……]

阅读全文

漫谈元编程

咬文嚼字

meta-programming(a.k.a.元编程) 中的这个 meta-词前缀源自希腊词,本意为“在…后,变换,以上”。经过几千年的演进,这个词前缀有了一种全新的意义:关于事物自身的事物。比如 meta-knowledge 就是“关于知识本身的知识”,meta-data 就是“关于数据的数据”,meta-language 就是“关于语言的语言”,而 meta-programming 也是由此而来,是“关于编程的编程”。

元编程

元编程算不上什么新鲜的概念,各种语言里早已有之:

  • C和Lisp系语言里的宏
  • C++里的模板
  • Java的注解
  • C#的属性和反射
  • [……]

阅读全文

Akka Streams: Using TCP

引子

准确来说,IO API 不算是 Akka Streams的内容,但它却是 Streaming IO (TCP) 的基础。

IO API 编程的第一步,是获取一个管理对象的引用。比如我们想针对TCP编程,可以这么获取 TCP Manager:

manager 是一个 actor 对象,用于处理底层 I/O资源和操作(诸如channels/selectors,或是workers的初始化),同时对于上层提供基于actor 模型的抽象

IO TCP

IO TCP 编程也是 CS 模型的,好处是不需要写繁琐的 S[……]

阅读全文

Akka Streams: Integrating with Actors

引子

Akka Streams 为异步编程提供了管道和流式接口,但如果我们希望结合 actor 模型的消息机制呢?Akka Streams提供了如下解决方案:

  • Sink.actorRef 产生 ActorRef,做为下游结点接收管道里的流数据
  • Source.actorRef 产生ActorRef,能被下游结点消费
  • Source.ActorPublisher 产生ActorRef,用于实现Reactive Streams中的Publisher
  • Sink.ActorSubscriber 产生ActorRef,用于实现Reactive Streams中的Subscriber[……]

阅读全文

Akka Streams: GraphStage

Stages

Stage 是 Akka Streams 里的核心概念,它代表了在Graph里的单位,是如何定义输入端口(Inlet)  / 输出端口(Outlet) 的;常用的基础形态有:

compose_shapes1

  • Source: 只有一个Outlet
  • Sink: 只有一个Inlet
  • Flow: 只有一个Outlet和一个Inlet
  • Fan-In: 多个Inlet一个Outlet
  • Fan-Out: 一个Inlet多个Outlet
  • BidiFlow: 双向通道,一对Inlet一对Outlet

有了这些基础件,我们可以按需组合出各种拓扑的图来:
runnable_graph1

自定义流处理

之前介绍过[……]

阅读全文