Crab213's Blog.

Crab213's Blog.

A monad is just a monoid in the category of endofunctors.

A Discipline of Programming 1: 系统与形式记号

本书简介以前曾经在图书馆看到过此书,当即就觉得很对胃口,可能与我研究过抽象代数有关。这本数更像是一本数学数,我认为它比《算法导论》更为严谨,本书展示了抽象与形式系统结合之后的威力。这本书并没有高深的算法,它主要是作者对编程的思考。 状态空间(state space)及其约束如果有稍微有点数学背景,甚至说只要上数学课稍微认真过一点,就会发现状态空间的思想无处不在,最典型的就是概率论中的样本空间。 我们从集合的角度看待变量的所有可能状态,这就是状态空间,与向量空间,样本空间是同本同源的。这样做的好处是,我们可以用预言(prediction)来过滤这个集合,筛选集合中的元素。因此,我们可以用一...

Floyd循环检测算法

循环检测问题在研究抽象代数的时候,很多教材都是从欧拉研究的循环群入手的,比如这本《Advanced Modern Algebra》。 当然,直接讨论数学有些扯远了,我们并不需要群论知识,锦上添花而已。考虑一个由连续自然数组成的集合M, 它由0到n-1的自然数组成,然后考虑一个映射f,它将M映射到它自身,亦即我们定义操作f。 由于f将M映射到M,对每个e∈M,f(e)总是有定义的,我们可以将某个元素e多次进行f操作。现在我们来考虑靠考虑这样做会发生什么?很显然,这样的操作会形成一个链条装的结构,比如映射f(e) = (e + 1) % n,取初始数据为0,n = 4,则可以得到: 0 -...

TCP/IP Sockets in Java:2 NIO

BufferBuffer对象代表一个缓冲区,是Channel中进行传输的基本单元。NIO中Channel与Selector的组合为我们提供了更加灵活的非阻塞IO解决方案。Buffer可看作一个定长数组,这个数组有四个索引,分别是position,mark,capacity及limit。 capacity是这个Buffer对象的容量,是不可变的。 limit的值代表第一个不可读写的数组元素的位置。 position是当前的操作位置。读写操作都是以position为起始位置。 mark的值是用户自定的一个标记。 Buffer对象内部的不变式: mark <= position &l...

TCP/IP Sockets in Java:1 TCP/UDP Socket

地址为了建立两台位于互联网中主机的连接,需要IP地址。Java中用InetAddress表示一个IP地址。然而,只有IP地址还不够,操作系统支持运行大量的进程,两台主机间的通信实质上变为了两个进程见的通信。为此TCP与UDP协议中都有端口号这一概念,应用程序在进行网络通信的时候会向操作系统请求占用某个端口号。所以一个TCP连接可以由连接双方的地址及端口号这个四元组唯一标识。 然而,IP地址对于用户并不是很友好,通过DNS我们可以将一个主机名与多个IP地址联系起来。我们只需要记住主机名,就可以通过DNS解析到对应的IP地址。这样做的好处是主机名比IP地址更加用户友好,同时,IP地址的变化可...

Java并发编程实践笔记6:线程池的应用

任务与执行策略的隐式耦合我们心目中的理想任务模型是任务之间是相互独立的,这样每个任务就可以独立执行。因此执行这样的任务的线程池的执行策略和任务直接是没有耦合的。我们可以任意选择执行策略,线程池中线程的数目也不受任何制约。 但是实际中还是有很多任务不是互相独立的,或者有其他特殊需求,这就会使任务和其执行策略有所联系,不是完全独立的。 非独立任务。某个任务可能会依赖其他任务的执行结果,或者起执行后发生的副作用。这样的任务会造成活性(liveness)问题,会限制线程池的大小。 使用了线程封闭的线程。使用线程封闭从而避免同步的线程自然而然需要顺序执行。即必须使用单线程的线程池。 使用Thre...

Java并发编程实践笔记5:取消与关闭

大多数情况下我们想让线程中的任务被完整执行,但是还是有例外的情况。对于有些任务,我们可能在它执行完毕之前就可能会发现它的结果已经不需要了,这时我们就希望有能提前终止任务的手段。在java中想要安全快速可靠地终止一个任务不适什么容易的事情,java语言本身没有提供安全地让线程强制停止的手段。相反,它提供了一种协同机制,让一个线程请求另一个线程,让其停止它所做的事情。 任务取消(Task Cancellation)如果一个外部代码让一个活动提前结束,我们称这个活动是可以取消的。有很多原因会导致我们想要取消一个活动: 用户请求取消。比如应用程序的用户需要让程序取消某一操作。 时限。有些操作可...

Java并发编程实践笔记4:任务执行

任务(task)是一个独立且彼此互不干涉的单元。在设计并发应用程序时,将程序划分成任务往往会简化程序结构,并且提供一个并行执行的自然子结构。 在线程中执行任务任务是独立的,并且不依赖于其他任务的状态,执行结果或者副作用。我们可以在线程中执行任务。我们有多种任务执行策略。 顺序执行所有任务 为每一个任务分配一个线程 使用固定数量的线程来执行所有任务 方案一就是在一个线程中一个一个的执行所有任务,缺点显而易见。所有任务顺序执行,没有很好的利用多处理器,其缺点与单线程程序是一样的。方案二是很多人一拍脑袋就能想出来的,但是也是有明显缺点的。我们不能控制线程的数目,线程数目可以无限大,这就可能...

Java并发编程实践笔记3:构建对象

我们不可能总是从头设计自己的程序,java语言本身提供了许多模块来帮助我们构建线程安全的多线程程序。 设计一个线程安全的类使用封装可以简化我们的工作,依靠良好的封装,我们可以更简单地确定一个类是否线程安全,或更更改一个线程安全的类。设计一个线程安全的类一般分为三步: 找出那些组成这个类状态的变量 找出那些约束状态变量的不变式 建立一种管理并发操作对象状态的机制 我们必须注意约束这个类的状态的不变式,一切同步行为都是以不变式为准。如果对一个变量的操作会违反不变式,造成类进入一个非法的状态,我们就应该将这个操作封装起来然后加以同步。如果不了结一个对象的不变式,那么你就无法保证线程安全。对...

Java并发编程实践笔记2:对象共享

写出正确的并发程序的关键问题就是管理对线程共享的可变状态的操作。我们需要处理两个问题:原子性和可视性。 可视性(visibility)问题当一个单线程程序执行的时候,我们自然而然认为我们对内存的操作是连贯的。比如,我们对一个变量x赋值,当我们紧接着这个赋值语句读取这个变量的值的时候,我们自然而然的认为这个x的值就是我们上一条赋值语句赋给他的值,但这在多线程环境下是行不通的。在多线程环境下,没有同步机制,我们无法确保在其他线程更改的状态能被当前线程立刻看到,这个操作已经不能基于简单的时序模型。如果一个线程在某个时刻改变了一个共享的状态,那么在这个时刻之后其他线程读取的这个状态值是无法保证被...
crab2313
slave get your ass back here ♂.
FRIENDS
friendA friendB