07 2021 档案

摘要:我们可以通过 Request 对象的 getSession 方法来获取 Session,并通过 Session 对象来读取和写入属性值。而 Session 的管理是由 Web 容器来完成的,主要是对 Session 的创建和销毁,除此之外 Web 容器还需要将 Session 状态的变化通知给监听者 阅读全文
posted @ 2021-07-30 16:11 hochan_100 阅读(366) 评论(0) 推荐(1)
摘要:每一个系统都有一些通用的模块,比如日志模块、异常处理模块、工具类等,对于 Tomcat 来说,比较重要的通用模块有日志、Session 管理和集群管理。 日志模块作为一个通用的功能,在系统里通常会使用第三方的日志框架。Java 的日志框架有很多,比如:JUL(Java Util Logging)、L 阅读全文
posted @ 2021-07-29 14:31 hochan_100 阅读(245) 评论(0) 推荐(0)
摘要:高性能程序就是高效的利用 CPU、内存、网络和磁盘等资源,在短时间内处理大量的请求。那如何衡量“短时间和大量”呢?其实就是两个关键指标:响应时间和每秒事务处理量(TPS)。 那什么是资源的高效利用呢? 我觉得有两个原则: 减少资源浪费。比如尽量避免线程阻塞,因为一阻塞就会发生线程上下文切换,就需要耗 阅读全文
posted @ 2021-07-29 11:00 hochan_100 阅读(259) 评论(0) 推荐(0)
摘要:图灵机 图灵机是一个抽象的模型,它是这样的:有一条无限长的纸带,纸带上有无限个小格子,小格子中写有相关的信息,纸带上有一个读头,读头能根据纸带小格子里的信息做相关的操作并能来回移动。 不理解?下面我再带你用图灵机执行一下“1+1=2”的计算,你就明白了。我们定义读头读到“+”之后,就依次移动读头两次 阅读全文
posted @ 2021-07-27 16:38 hochan_100 阅读(443) 评论(0) 推荐(0)
摘要:我们这次主要讨论 Go 语言的数组(array)类型和切片(slice)类型。数组和切片有时候会让初学者感到困惑。 它们的共同点是都属于集合类的类型,并且,它们的值也都可以用来存储某一种类型的值(或者说元素)。 不过,它们最重要的不同是:数组类型的值(以下简称数组)的长度是固定的,而切片类型的值(以 阅读全文
posted @ 2021-07-27 15:39 hochan_100 阅读(97) 评论(0) 推荐(0)
摘要:Java 对象,特别是一个比较大、比较复杂的 Java 对象,它们的创建、初始化和 GC 都需要耗费 CPU 和内存资源,为了减少这些开销,Tomcat 和 Jetty 都使用了对象池技术。 所谓的对象池技术,就是说一个 Java 对象用完之后把它保存起来,之后再拿出来重复使用,省去了对象创建、初始 阅读全文
posted @ 2021-07-27 14:27 hochan_100 阅读(147) 评论(0) 推荐(0)
摘要:要在运行的过程中升级 Web 应用,如果你不想重启系统,实现的方式有两种:热加载和热部署。 那如何实现热部署和热加载呢?它们跟类加载机制有关,具体来说就是: 热加载的实现方式是 Web 容器启动一个后台线程,定期检测类文件的变化,如果有变化,就重新加载类,在这个过程中不会清空 Session ,一般 阅读全文
posted @ 2021-07-26 10:21 hochan_100 阅读(1617) 评论(0) 推荐(0)
摘要:相比较 Tomcat 的连接器,Jetty 的 Connector 在设计上有自己的特点。 Jetty 的 Connector 支持 NIO 通信模型,我们知道 NIO 模型中的主角就是 Selector,Jetty 在 Java 原生 Selector 的基础上封装了自己的 Selector,叫作 阅读全文
posted @ 2021-07-23 18:14 hochan_100 阅读(268) 评论(0) 推荐(0)
摘要:在开发中我们经常会碰到“池”的概念,比如数据库连接池、内存池、线程池、常量池等。为什么需要“池”呢?程序运行的本质,就是通过使用系统资源(CPU、内存、网络、磁盘等)来完成信息的处理,比如在 JVM 中创建一个对象实例需要消耗 CPU 和内存资源,如果你的程序需要频繁创建大量的对象,并且这些对象的存 阅读全文
posted @ 2021-07-23 17:52 hochan_100 阅读(55) 评论(0) 推荐(0)
摘要:我们在使用 Tomcat 时,会在启动日志里看到这样的提示信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found 阅读全文
posted @ 2021-07-22 18:21 hochan_100 阅读(197) 评论(0) 推荐(1)
摘要:UNIX 系统下的 I/O 模型有 5 种:同步阻塞 I/O、同步非阻塞 I/O、I/O 多路复用、信号驱动 I/O 和异步 I/O。这些名词我们好像都似曾相识,但这些 I/O 通信模型有什么区别?同步和阻塞似乎是一回事,到底有什么不同?等一下,在这之前你是不是应该问自己一个终极问题:什么是 I/O 阅读全文
posted @ 2021-07-22 16:05 hochan_100 阅读(142) 评论(0) 推荐(0)
摘要:经过前面几期的学习,相信你对 Tomcat 的整体架构和工作原理有了基本了解。但是 Servlet 容器并非只有 Tomcat 一家,还有别的架构设计思路吗?今天我们就来看看 Jetty 的设计特点。 Jetty 是 Eclipse 基金会的一个开源项目,和 Tomcat 一样,Jetty 也是一个 阅读全文
posted @ 2021-07-20 15:21 hochan_100 阅读(362) 评论(0) 推荐(0)
摘要:上面这张图描述了组件之间的静态关系,如果想让一个系统能够对外提供服务,我们需要创建、组装并启动这些组件;在服务停止的时候,我们还需要释放资源,销毁这些组件,因此这是一个动态的过程。也就是说,Tomcat 需要动态地管理这些组件的生命周期。 在我们实际的工作中,如果你需要设计一个比较大的系统或者框架时 阅读全文
posted @ 2021-07-20 10:14 hochan_100 阅读(46) 评论(0) 推荐(0)
摘要:今天我们一起来看一下 Tomcat 的容器设计。先复习一下,上期我讲到了 Tomcat 有两个核心组件:连接器和容器,其中连接器负责外部交流,容器负责内部处理。具体来说就是,连接器处理 Socket 通信和应用层协议的解析,得到 Servlet 请求;而容器则负责处理 Servlet 请求。我们通过 阅读全文
posted @ 2021-07-19 16:20 hochan_100 阅读(45) 评论(0) 推荐(0)
摘要:Tomcat 总体架构 我们知道如果要设计一个系统,首先是要了解需求。通过专栏前面的文章,我们已经了解了 Tomcat 要实现 2 个核心功能: 处理 Socket 连接,负责网络字节流与 Request 和 Response 对象的转化。 加载和管理 Servlet,以及具体处理 Request 阅读全文
posted @ 2021-07-19 15:29 hochan_100 阅读(67) 评论(0) 推荐(0)
摘要:异常:硬件、系统和应用的组合拳 一提到计算机当中的异常(Exception),可能你的第一反应就是 C++ 或者 Java 中的 Exception。不过我们今天讲的,并不是这些软件开发过程中遇到的“软件异常”,而是和硬件、系统相关的“硬件异常”。 当然,“软件异常”和“硬件异常”并不是实际业界使用 阅读全文
posted @ 2021-07-19 10:30 hochan_100 阅读(116) 评论(0) 推荐(0)
摘要:我们之前讲过,程序的链接,是把对应的不同文件内的代码段,合并到一起,成为最后的可执行文件。这个链接的方式,让我们在写代码的时候做到了“复用”。同样的功能代码只要写一次,然后提供给很多不同的程序进行链接就行了。 么说来,“链接”其实有点儿像我们日常生活中的标准化、模块化生产。我们有一个可以生产标准螺帽 阅读全文
posted @ 2021-07-16 11:18 hochan_100 阅读(21) 评论(0) 推荐(0)
摘要:介绍过 Java SDK 提供了 2 个有界队列:ArrayBlockingQueue 和 LinkedBlockingQueue,它们都是基于 ReentrantLock 实现的,在高并发场景下,锁的效率并不高,那有没有更好的替代品呢?有,今天我们就介绍一种性能更高的有界队列:Disruptor。 阅读全文
posted @ 2021-07-15 17:44 hochan_100 阅读(119) 评论(0) 推荐(0)
摘要:大部分程序员开发的都是应用系统。在开发应用系统的时候,我们遇到的性能瓶颈大部分都在 I/O 上。 讲解局部性原理的时候,我们一起看了通过把内存当作是缓存,来提升系统的整体性能。在讲解 CPU Cache 的时候,我们一起看了 CPU Cache 和主内存之间性能的巨大差异。 然而,我们知道,并不是所 阅读全文
posted @ 2021-07-14 13:57 hochan_100 阅读(134) 评论(0) 推荐(0)
摘要:接口和设备:经典的适配器模式 实际上,输入输出设备,并不只是一个设备。大部分的输入输出设备,都有两个组成部分。第一个是它的接口(Interface),第二个才是实际的 I/O 设备(Actual I/O Device)。我们的硬件设备并不是直接接入到总线上和 CPU 通信的,而是通过接口,用接口连接 阅读全文
posted @ 2021-07-14 09:55 hochan_100 阅读(45) 评论(0) 推荐(0)
摘要:如果我再问你,计算机五大组成部分是什么,应该没有人不知道了吧?我们这一节要讲的内容,依然要围绕这五大部分,控制器、运算器、存储器、输入设备和输出设备。 CPU 所代表的控制器和运算器,要和存储器,也就是我们的主内存,以及输入和输出设备进行通信。 那问题来了,CPU 从我们的键盘、鼠标接收输入信号,向 阅读全文
posted @ 2021-07-13 18:25 hochan_100 阅读(129) 评论(0) 推荐(0)
摘要:机器指令里面的内存地址都是虚拟内存地址。程序里面的每一个进程,都有一个属于自己的虚拟内存地址空间。我们可以通过地址转换来获得最终的实际物理地址。我们每一个指令都存放在内存里面,每一条数据都存放在内存里面。因此,“地址转换”是一个非常高频的动作,**“地址转换”**的性能就变得至关重要了。 这就是我们 阅读全文
posted @ 2021-07-13 18:10 hochan_100 阅读(97) 评论(0) 推荐(0)
摘要:计算机有五大组成部分,分别是:运算器、控制器、存储器、输入设备和输出设备。 如果说计算机最重要的组件,是承担了运算器和控制器作用的 CPU,那内存就是我们第二重要的组件了。内存是五大组成部分里面的存储器,我们的指令和数据,都需要先加载到内存里面,才会被 CPU 拿去执行。 可以知道,在我们日常使用的 阅读全文
posted @ 2021-07-13 16:39 hochan_100 阅读(67) 评论(0) 推荐(0)
摘要:你平时用的电脑,应该都是多核的 CPU。多核 CPU 有很多好处,其中最重要的一个就是,它使得我们在不能提升 CPU 的主频之后,找到了另一种提升 CPU 吞吐率的办法。 我们说,CPU Cache 解决的是内存访问速度和 CPU 的速度差距太大的问题。而多核 CPU 提供的是,在主频难以提升的时候 阅读全文
posted @ 2021-07-13 14:44 hochan_100 阅读(75) 评论(0) 推荐(0)
摘要:在我工作的十几年里,写了很多 Java 的程序。同时,我也面试过大量的 Java 工程师。对于一些表示自己深入了解和擅长多线程的同学,我经常会问这样一个面试题:“volatile 这个关键字有什么作用?”如果你或者你的朋友写过 Java 程序,不妨来一起试着回答一下这个问题。 就我面试过的工程师而言 阅读全文
posted @ 2021-07-13 11:36 hochan_100 阅读(25) 评论(0) 推荐(0)
摘要:int[] arr = new int[64 * 1024 * 1024]; // 循环1 for (int i = 0; i < arr.length; i++) arr[i] *= 3; // 循环2 for (int i = 0; i < arr.length; i += 16) arr[i] 阅读全文
posted @ 2021-07-13 09:49 hochan_100 阅读(72) 评论(0) 推荐(0)
摘要:平时进行服务端软件开发的时候,我们通常会把数据存储在数据库里。而服务端系统遇到的第一个性能瓶颈,往往就发生在访问数据库的时候。这个时候,大部分工程师和架构师会拿出一种叫作“缓存”的武器,通过使用 Redis 或者 Memcache 这样的开源软件,在数据库前面提供一层缓存的数据,来缓解数据库面临的压 阅读全文
posted @ 2021-07-09 18:25 hochan_100 阅读(109) 评论(0) 推荐(0)
摘要:如果你自己组装过 PC 机,你肯定知道,想要 CPU,我们只要买一个就好了,但是存储器,却有不同的设备要买。比方说,我们要买内存,还要买硬盘。买硬盘的时候,不少人会买一块 SSD 硬盘作为系统盘,还会买上一块大容量的 HDD 机械硬盘作为数据盘。内存和硬盘都是我们的存储设备。而且,像硬盘这样的持久化 阅读全文
posted @ 2021-07-09 17:57 hochan_100 阅读(129) 评论(0) 推荐(0)
摘要:摘要: 原创出处 http://cmsblogs.com/?p=2197 「小明哥」欢迎转载,保留摘要,谢谢! 在前面提到过,AQS 是构建 Java 同步组件的基础,我们期待它能够成为实现大部分同步需求的基础。 AQS 的设计模式采用的模板方法模式,子类通过继承的方式,实现它的抽象方法来管理同步状 阅读全文
posted @ 2021-07-08 18:21 hochan_100 阅读(61) 评论(0) 推荐(0)
摘要:摘要: 原创出处 http://cmsblogs.com/?p=2174 「小明哥」欢迎转载,保留摘要,谢谢! Java 的内置锁一直都是备受争议的,在 JDK 1.6 之前,synchronized 这个重量级锁其性能一直都是较为低下,虽然在 1.6 后,进行大量的锁优化策略。 但是与 Lock 阅读全文
posted @ 2021-07-08 17:37 hochan_100 阅读(98) 评论(0) 推荐(0)
摘要:摘要: 原创出处 http://cmsblogs.com/?p=2188 「小明哥」欢迎转载,保留摘要,谢谢! 1. 简介 CLH 同步队列是一个 FIFO 双向队列,AQS 依赖它来完成同步状态的管理: 当前线程如果获取同步状态失败时,AQS则会将当前线程已经等待状态等信息构造成一个节点(Node 阅读全文
posted @ 2021-07-08 17:12 hochan_100 阅读(50) 评论(0) 推荐(0)
摘要:首先我们来看看 Guava RateLimiter 是如何解决高并发场景下的限流问题的。Guava 是 Google 开源的 Java 类库,提供了一个工具类 RateLimiter。我们先来看看 RateLimiter 的使用,让你对限流有个感官的印象。假设我们有一个线程池,它每秒只能处理两个任务 阅读全文
posted @ 2021-07-07 15:45 hochan_100 阅读(595) 评论(0) 推荐(0)
摘要:ThreadLocal 的工作原理 在解释 ThreadLocal 的工作原理之前, 你先自己想想:如果让你来实现 ThreadLocal 的功能,你会怎么设计呢?ThreadLocal 的目标是让不同的线程有不同的变量 V,那最直接的方法就是创建一个 Map,它的 Key 是线程,Value 是每 阅读全文
posted @ 2021-07-06 15:19 hochan_100 阅读(91) 评论(0) 推荐(0)
摘要:摘要: 原创出处 http://www.cnblogs.com/peida/p/Guava_Multimap.html 「竹子」欢迎转载,保留摘要,谢谢! BiMap提供了一种新的集合类型,它提供了key和value的双向关联的数据结构。 通常情况下,我们在使用Java的Map时,往往是通过key来 阅读全文
posted @ 2021-07-05 15:26 hochan_100 阅读(87) 评论(0) 推荐(0)
摘要:摘要: 原创出处 http://www.cnblogs.com/peida/p/Guava_Range.html 「竹子」欢迎转载,保留摘要,谢谢! 在Guava中新增了一个新的类型Range,从名字就可以了解到,这个是和区间有关的数据结构。从Google官方文档可以得到定义:Range定义了连续跨 阅读全文
posted @ 2021-07-05 15:15 hochan_100 阅读(131) 评论(0) 推荐(0)
摘要:摘要: 原创出处 http://www.cnblogs.com/peida/p/Guava_Objects.html 「竹子」欢迎转载,保留摘要,谢谢! 在Java中Object类是所有类的父类,其中有几个需要override的方法比如equals,hashCode和toString等方法。每次写这 阅读全文
posted @ 2021-07-05 14:53 hochan_100 阅读(53) 评论(0) 推荐(0)
摘要:摘要: 原创出处 http://www.cnblogs.com/peida/p/Guava_Preconditions.html 「竹子」欢迎转载,保留摘要,谢谢! 在日常开发中,我们经常会对方法的输入参数做一些数据格式上的验证,以便保证方法能够按照正常流程执行下去。对于可预知的一些数据上的错误,我 阅读全文
posted @ 2021-07-05 14:38 hochan_100 阅读(112) 评论(0) 推荐(0)
摘要:摘要: 原创出处 http://www.cnblogs.com/peida/archive/2013/06/14/Guava_Optional.html 「竹子」欢迎转载,保留摘要,谢谢! null 代表不确定的对象 null 本身不是对象,也不是 Objcet 的实例 null 对象的使用 Gua 阅读全文
posted @ 2021-07-05 14:30 hochan_100 阅读(273) 评论(0) 推荐(0)
摘要:摘要: 原创出处 http://www.cnblogs.com/peida/p/Guava_Multimap.html 「竹子」欢迎转载,保留摘要,谢谢! Multimap Multimap的实现 在日常的开发工作中,我们有的时候需要构造像Map<K, List>或者Map<K, Set>这样比较复 阅读全文
posted @ 2021-07-05 09:53 hochan_100 阅读(83) 评论(0) 推荐(0)
摘要:文件系统的功能规划 对于运行的进程来说,内存就像一个纸箱子,仅仅是一个暂存数据的地方,而且空间有限。 如果我们想要进程结束之后,数据依然能够保存下来,就不能只保存在内存里,而是应该保存在外部存储中。就像图书馆这种地方,不仅空间大,而且能够永久保存。 我们最常用的外部存储就是硬盘,数据是以文件的形式保 阅读全文
posted @ 2021-07-02 18:14 hochan_100 阅读(37) 评论(0) 推荐(0)
摘要:如何提升内存分配的效率? 或许有同学会认为,我又不写底层框架,内存分配也依赖虚拟机,并不需要应用开发者了解。如果你也这么认为,我们不妨看看这个例子:在 Linux 系统中,用 Xmx 设置 JVM 的最大堆内存为 8GB,但在近百个并发线程下,观察到 Java 进程占用了 14GB 的内存。为什么会 阅读全文
posted @ 2021-07-02 17:29 hochan_100 阅读(605) 评论(0) 推荐(0)
摘要:Buffer 和 Cache 的设计目的,是为了提升系统的 I/O 性能。它们利用内存,充当起慢速磁盘与快速 CPU 之间的桥梁,可以加速 I/O 的访问速度。 Buffer 和 Cache 分别缓存的是对磁盘和文件系统的读写数据。 从写的角度来说,不仅可以优化磁盘和文件的写入,对应用程序也有好处, 阅读全文
posted @ 2021-07-02 17:09 hochan_100 阅读(106) 评论(0) 推荐(0)
摘要:回顾一下系统的内存使用情况,比如下面这个 free 输出界面: # 注意不同版本的free输出可能会有所不同 $ free total used free shared buff/cache available Mem: 8169348 263524 6875352 668 1030472 7611 阅读全文
posted @ 2021-07-02 16:29 hochan_100 阅读(122) 评论(0) 推荐(0)
摘要:提问:物理的页面是如何管理的? 物理内存的组织方式 涉及物理内存的映射的时候,我们总是把内存想象成它是由连续的一页一页的块组成的。我们可以从 0 开始对物理页编号,这样每个物理页都会有个页号。 由于物理地址是连续的,页也是连续的,每个页大小也是一样的。因而对于任何一个地址,只要直接除一下每页的大小, 阅读全文
posted @ 2021-07-02 15:54 hochan_100 阅读(61) 评论(0) 推荐(0)
摘要:32 位系统和 64 位系统的内存布局有的地方相似,有的地方差别比较大 用户态和内核态的划分 从 task_struct 出发来看。这里面有一个 struct mm_struct 结构来管理内存。 struct mm_struct *mm; 在 struct mm_struct 里面,有这样一个成员 阅读全文
posted @ 2021-07-02 12:37 hochan_100 阅读(42) 评论(0) 推荐(0)
摘要:内存管理是操作系统最核心的功能之一。内存主要用来存储系统和应用程序的指令、数据、缓存等。 内存映射 我们平常所说的笔记本内存,指的是物理内存,也称主存。只有内核菜可以直接访问物理内存,那么,进程要访问内存时,该怎么操作? Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连 阅读全文
posted @ 2021-07-01 16:24 hochan_100 阅读(212) 评论(0) 推荐(0)