Algorithms in AI
Chapter 0. Intro0.1 The definition of Artificial Intelligence
Think rationally -> Think like people -> Act like people -> Act rationally.
The system maximumly achieving predefined goals.
-> Maximize the expected utility. (最大化预期效用)
Brains and AI
Why not reverse engineering the brains? -> Not as modular as software.
But there are the lessons learned from the brain (interleave, 交织在一起):
Memory (data): Judge situations depending on the previous experiences (statistics).
e.g., Ba ...
Convex & Optimizations
Chapter 1. Overview进入本章前复习基础的数学知识:
Vector Norms(范数):对于向量 $x=(x_1,x_2,\ldots,x_n)$,$l_p$-norm 定义为:
||x||_p={}^p\sqrt{|x|_1^p+|x|_2^p+\cdots+|x|_n^p}正定性:$||x||_p\ge0,\space||x||_p=0\space\iff x=0$;
非线性性:$||tx||=|t|\space||x||,\space t\in\mathbf{R}$,$||x+y||\le||x||+||y||$(这个不等式并不好证。好证的三角不等式仅限于范数为 2 的特殊情况);
正交阵 $A^TA=I$,因此一定满秩。此外正交阵列向量(或行)一定是相互正交的向量组,且模长为 1(单位正交向量,否则 $A^TA$ 就不是单位向量了)。
正交阵可以进行对角化 $A=P^{-1}BP$($B$ 为对角阵,$P$ 为满秩矩阵)。所谓对角化可以感性理解为将这些正交向量组移动到与给定坐标轴的单位向量方向一致的方向上。
正交变换非常好的性质是 保范性。向量经过正交变换 ...
Numeric Analysis for Beginners
Chapter 1. Basic Concepts
相对误差与绝对误差;
求根问题:$\text{For }f:\mathbf{R}\rightarrow\mathbf{R},\text{ find }x^\text{ such that }f(x^)=0$;
假设有估计解 $x_{est}$,但是 $0\lt |f(x_{est})|\ll1$,那么我们也许不知道 $|x_{est}-x_0|$,但是我们一定知道 $|f(x_{est})-f(x_0)|\equiv|f(x_{est})|$;
前向误差:估计解与实际解的差值(就是上面的 $|x_{est}-x_0|$,一般我们不知道);
后向误差:使得估计值正确所要让 problem statement 改变的 delta(就是上面的 $|f(x_{est})-f(x_0)|\equiv|f(x_{est})|$,一般我们能算出来);
Well-Conditioned(insensitive):$\text{Small backward error}\Rightarrow\text{Small forward error}$ ...
Introduction to Rabbit MQ
Chapter 0. 背景0.1 同步消息和异步消息微服务架构下存在很多服务间相互调用的情况。
我们知道可以通过 OpenFeign 的方式来获取远程服务的响应,但是 OpenFeign 的远程调用是同步的,其优点是同步调用时效强,等待结果返回。但同时会导致:
代码可扩展性差。
性能堪忧。相较于相同项目实现的单体架构,同步的微服务调用方式会多出网络等待时间。
于是我们需要异步调用的方式,这里使用到了发布-订阅者模式。
异步调用的优势是,
模块间进一步解耦(发布者和订阅者间无需知道相互之间的信息);
可拓展性强(scalable),添加实例无需更改代码;
异步性能有明显提升;
故障隔离(最终一致性保证);
缓存消息,实现流量削峰填谷;
但是缺点也很明显:
异步实现无法立即得到结果,时效性差,可能导致数据不一致性;
不作额外措施,则不能保证最终一致性(下游业务是否成功)。所以业务安全依赖于 broker 的可靠性;
0.2 Message Queue 选型
Opt
RabbitMQ
ActiveMQ
RocketMQ
Kafuka
Company
Rabbit(专 ...
微服务初探
Chapter 0. 基本概念
微服务是一种软件架构风格。专注于单一职责的小型业务为基础,组成复杂大型应用。
需要解决的问题:服务拆分、远程调用(RPC)、服务治理(可用性与调度)、请求路由、身份认证、配置管 理、分布式事务(一致性问题)、异步通信……
优点和特征:粒度小、单服务开发便捷,团队自治,服务自治,系统耦合性低;
缺点:跨模块开发难度大,运维成本高;
对比而言,单体架构:
优点:架构简单、部署成本低(适用于开发功能相对简单、规模较小的项目);
缺点:团队协作成本高,系统发布效率低、系统可用性差(软件可靠性差);
对应框架:Spring Cloud,全球范围广泛使用的微服务框架;
服务注册发现组件:Eureka、Nacos、Consul……
服务远程调用(RPC);OpenFeign、Dubbo……
服务链路监控:Zipkin、Sleuth……
统一配置管理:Spring Cloud Config、Nacos……
统一网关路由:Spring Cloud Gateway、Zuul……
流控、降级、保护:Hystix、Sentinel……
Chapter 1. 基 ...
Semaphore, Mutex, CV
学习 ICS 的并行一章之后,笔者有些疑惑,semaphore(信号量)、mutex(互斥锁)、conditional variables(条件变量)这 3 者之间究竟该怎么区分它们的使用场景?
首先我们需要去阐述清楚它们各自的定义和效果。
学术界认为 mutex 是 semaphore 的特例,因此像著名的书籍 CSAPP 就先以 semaphore 为例讲了讲并发程序的资源控制问题。但是实际上有相当一部分实践派和语义派认为二者不应该混为一谈。像 Linus 本人在一次将 Linux 内核的一部分 semaphore 重构为 mutex 后,发现不仅改善了代码语义,还在一定程度上提升了性能。这件事也说明了,虽然在理论上一方可以替代另一方,但实践上它们各有所长。
Semaphore vs Mutex我们先讨论 semaphore。
CSAPP 中先从 “线程间变量共享” 的情况说起,它指出,程序对内存的更改并不直接在内存上完成,在汇编中可以看到,大致经历了 load(从内存到 CPU 寄存器)、update(在 CPU 寄存器内更新数据)、store(将 CPU 寄存器数据写回内存)这 ...
Java Spring Boot 入门
前置条件:WEB 基础(Socket,HTTP 整套规范),SQL 和数据库基础,Java 语言基础、前端基础(至少了解一种前端框架,本文以 React 为例);
Chapter 0. Basic Concepts0.1 Servlet, war & jar在接触 Web 框架时,你肯定能碰到一个绕不开的词:Servlet。它是什么?
Servlet 本质上就是一种规范,在 Java 的实现中就是一个 Web 规范接口。
所以,为什么要有这个规范?让我们回到最初的起点。
假设你什么框架都不用,想要徒手写一个能提供服务的服务器,那需要做哪些工作?
其实原理比较简单,遵循当今互联网的 HTTP 协议发报文就行:
先编写基于多线程的 TCP 服务(Web 3.0 准备改用 UDP 了);
然后在一个 TCP 连接中读取 HTTP 请求,发送 HTTP 响应即可;
但是其中还要考虑一些与网络协议相关、与业务逻辑无关的其他情况:
识别正确和错误的 HTTP 请求;
识别正确和错误的 HTTP 头;
复用 TCP 连接;
复用线程;
IO 异常处理;
…
说到这里头都大了🥹 ...
Java 学习笔记(二)
Reference: Oracle Documentation
Chapter 3. Java Record & Java Bean3.1 Java Record在 Java 14 以后,官方引入了新的 Java 关键字:record;
那么这个 record 关键字究竟有什么用处呢?它和我们熟知的 class / interface / abstract class 又有什么区别呢?其实在 Java 14 以前,有一种需求写起来非常的麻烦,正因为这种需求才产生出了 record 关键字。这个需求是什么呢?
举个例子,假如现在有个应用场景,想要定义一个数据类型,它只是用来存放一些数据(例如数据库查询的结果,或者是某个服务的返回信息)。
在很多实际情况下,我们希望使用这些数据就像 Java 内置基本类型一样,是不可变数据类型。这样做有几点好处:
复制构造时,不是引用传递,因此是深拷贝。这样使用起来和基本类型一样方便,但是又不用担心改错源数据(非引用链接);
确保数据在多线程情况下无需同步,线程安全!
回忆下基础篇中的知识,要让 Java 类型(对象)behaves lik ...
CSAPP Notes: ECF & I/O
Chapter 13. Exceptional Control Flow
对应书中第 8 章。
异常控制流是现代计算机系统的一个相当重要的部分。
13.1 Control Flow
控制流:从机器打开到关闭的过程中,处理器只做一件事:读指令、执行指令,一个周期做一个指令。多核的机器则每个核心依次交替执行指令。这些指令序列被称为控制流。硬件正在执行的实际指令序列就被称为物理控制流。
改变内存中控制流的方法:分支 & 跳转,过程调用 & 返回(Branches & Jumps & Procedure call and return);
都是对于程序状态变化的处理。
但以上的简单的改变控制流的方法对于处理复杂的系统级别的状态变化时,就显得非常拙劣。(例如 OS 协同软硬件的通信,如果还是以 if-else 的方法,那将会非常差劲);
什么是 “系统级别的状态变化”?
数据从磁盘 / 网卡到达内存中;
I/O 设备输入 Ctrl+C;
系统分时复用的时钟到期了,接下来要打断当前执行的进程;
除零指令;
……
这些事件不能指望应用程序的开发者来解决 ...
CSAPP Notes: Memory Hierarchy & Cache & Opt
Chapter 10. The Memory Hierarchy
本章将介绍系统的内存分层架构。
之前几章,我们对于内存的理解就是一个很大的字节数组,可以用地址作为下标进行访问。但事实上,真正的计算机的存储系统背后的设备层次结构设计远比这层抽象要复杂。
正是计算机的存储系统的层次结构对有限、离散资源的管理和抽象,才能让程序的内存看起来呈现出这种线性的数组结构。本章就来讨论计算机存储系统背后的层次结构。
10.1 Storage Technologies & Trends在正式学习存储系统的层次结构前,有必要稍微弄清楚底层硬件的情况。
10.1.1 Random-Access Memory (RAM)当前大多数人所熟知的 “内存” 的一部分就是随机访问存储器(RAM),它具有以下的特征:
RAM 是个存储元件,I/O 吞吐速率快于绝大多数硬盘固件/磁盘(称为 “外存”);
RAM 常常被打包放在 CPU 芯片中;
RAM 中每一个基本的存储单元被称为 单元胞(Cell),一个单元胞中存放 1 bit 数据;
很多个 RAM 芯片共同工作,组成了计算机的 主存(主存储器) ...