读书笔记:《深入分析Java Web技术内幕》

第1章:深入Web请求过程
主要讲解了web请求流程涉及到的内容。包含B/S架构、简单的HTTP信息、DNS解析、CDN工作机制等。

第2章:深入Java I/O的工作机制
1、Java的I/O操作类可分成四组
①基于字节操作的I/O接口:InputStream和OutputStream
②基于字符操作的I/O接口:Writer和Reader
③基于磁盘操作的I/O接口:File
④基于网络操作的I/O接口:Socket
前两组是传输数据的数据格式,后两组是传输数据的方式。I/O的核心问题也就是将什么样的数据(数据格式)如何写(传输方式)到什么地方的问题。数据格式和传输方式是影响效率的最关键因素。
2、磁盘I/O工作机制——几种访问文件的方式
①标准访问文件的方式(磁盘->系统内存->用户内存)
②直接I/O的方式(磁盘->用户内存)
③同步访问文件的方式
④异步访问文件的方式
⑤内存映射的方式
3、Java序列化复杂情况总结
①当父类基础Serializable接口时,所有子类都可以被序列化。
②子类实现了Serializable接口,父类没有实现,父类中的属性不能序列化(不报错,数据丢失),但是在子类中属性仍能正确序列化。
③如果序列化的属性是对象,则这个对象也必须实现Serializable接口,否则会报错。
④在反序列化时,如果对象的属性有修改或删减,则修改的部分属性会丢失,但不会报错。
⑤在反序列化时,如果serialVersionUID被修改,则反序列化会失败。
4、影响网络传输的因素
①网络带宽
②传输距离
③TCP拥塞控制
5、BIO存在的问题及NIO的工作机制
关键点:一个线程用来处理所有连接的数据交互请求,每个连接的数据交互都不是阻塞方式,所以可以同时处理大量的连接请求。
6、Buffer的工作方式
ByteBuffer,一组基本数据类型的元素列表,通过四个索引来保存这个数据的当前状态
capacity:缓冲区数组的总长度;
position:下一个要操作的数据元素的位置
limit:缓冲区数组中不可操作的下一个元素的位置,limit<=capacity
mark:用于记录当前position的前一个位置或者默认是0,方便操作回退。
7、DirectByteBuffer与Non-Direct Buffer对比:P48
8、NIO的数据访问方式,NIO提供了两个优化的文件访问方式.
①FileChannel.transferTo&FileChannel.transferForm:数据之间在内核空间中移动,减少数据从内核到用户空间的复制。
②FileChannel.mao:内存映射的方式,直接操作文件数据。
9、磁盘I/O优化(P50)
10、本章后面的部分,就是常见的概念以及Java,IO中用到的设计模式,比如适配器、装饰器模式,这部分讲的不是很贴切,当然,这本书可能作用就是广而不深吧。

第4章:Javac编译原理
1、Javac
Javac的主要任务就是将Java源代码语言先转化成JVM能够识别的语言,JVM将JVM语言转化成当前机器能够识别的机器语言。
2、Java编译器
编译过程:源码->Token流->语法树->注解语法数->字节码
源码经过的组件顺序为:词法分析器组件->语法分析器组件->语义分析器组件->代码生成器组件(class字节码,栈,逆波兰式(后缀表达式)),具体java内部的组件实现可以参考书中内容。
3、访问者模式

第5章:深入class文件结构
.class文件的组织结构,表达形式。无非是一种格式表达形式,需要解决问题时再细研就好了。

第6章:深入分析ClassLoader工作机制
1、ClassLoader类结构,双亲委派机制
2、加载class过程,校验文件合法->加载class->加载class里依赖的其他class
3、常见加载类异常
ClassNotFoundException
NoClassDefFoundError
UnsatisfiedLinkError
ClassCastException
ExceptionInInitializerError
4、自定义ClassLoader
5、Tomcat类加载机制

第7章:JVM体系结构与工作方式
1、JVM体系结构(这个文章一堆,不记太细了)
2、基于寄存器更方便数据的操作,但是JVM为何选择基于栈的架构
①JVM要设计成与平台无关的,而平台无关性就要保证在没有或者有很少的寄存器的机器上也要同样能正确的执行Java代码。
②为了指令的紧凑性,因为Java的字节码可能在网络上传输,所以class文件的大小也是设计Jvm字节码指令的一个重要因素,如在class文件中字节码除了处理两个表跳转的指令外,其他都是字节对齐的,操作码可以只占一个字节大小,这都是为了尽量让编译后的class文件更加紧凑。
3、执行引擎的架构设计(P187~188)
每当创建一个新的线程时,JVM会为这个线程创建一个Java栈,同时会为这个线程分配一个PC寄存器,并且这个PC寄存器会指向这个线程的第一行可执行代码。每当调用一个方法时会在这个栈上创建一个新的栈帧数据结构,这个栈帧会保留这个方法的一些元信息,如在这个方法中定义的局部变量、一些用来支持常量池的解析、正确方法返回及异常处理机制等。

第8章:JVM内存管理
1、首先是操作系统相关的知识:物理内存与虚拟内存、内核空间与用户空间、通常的内存分配策略(静态内存分配、栈内存分配、堆内存分配)
2、Java中运行时需要内存的地方:Java堆、线程、类和类加载器、NIO、JNI(Java Native Interface)
3、JVM内存结构:PC寄存器、Java栈、堆、方法区、运行时常量池、本地方法栈
4、JVM内存分配。堆主要用来存放对象,栈的分配则和线程绑定在一起,主要用来执行程序。这种不同主要是由栈和堆的特点决定的。
5、JVM内存回收策略。包含静态内存、动态内存分配和回收,如何检测垃圾( 可达性分析算法)及分代算法。
6、实际的发生内存泄漏的例子。

第9章:Servlet工作原理解析
1、Servlet与Servlet容器之间通过标准化接口相互协作。但它们是彼此依存,独立发展的,这一切都是为了适应工厂化生产。
2、Servlet容器启动、Servlet初始化、Servlet的体系结构。
3、Request、Response、Listener、Filter、url-pattern

第11章:Tomcat的系统架构与设计模式
1、Tomact的总体结构,p287;一个Container可以有多个Connector。多个Connector和一个Container形成了一个Service。一个Server包含了多个Service。
2、组件的生命线“Lifecycle”,Tomcat中组件的生命周期是通过Lifecycle接口来控制,组件只要继承这个接口,实现这个方法,就可以统一被拥有它的组件控制。一层层直到一个最高级的组件就可以控制Tomcat中所有组件的生命周期。还实现了观察者模式,进而可以执行其他操作。
3、Connector组件是Tomcat中的两个核心组件之一,主要任务是接受浏览器发出的TCP请求,创建一个Request和Response对象分别用于和请求端交换数据。然后会分配一个线程来处理这个请求,并把产生的Request和Response对象传给处理这个请求的线程,处理这个请求的线程就是Container组件要做的事。P294
4、Container是Servlet容器,由Engine、Host、Context、Wrapper组成,每个组件都可以定义自己的pipeline
  • Engine容器比较简单,它只定义了一些基本的关联关系。
  • Host是Engine的子容器,一个Host在Engine中代表一个虚拟主机,这个虚拟主机的作用就是运行多个应用,它负责安装和展开这些应用,并且标识这个应用以便能够区分他们。
  • Context容器代表Servlet的Context,它具备了Servlet运行的基本环境,理论上只要有Context就能运行Servlet了。简单的Tomcat可用没有Engine和Host。
  • Wrapper代表一个Servlet,它负责管理一个Servlet,包括Servlet的装载、初始化、执行及资源回收。
5、Tomcat中的设计模式
  • 门面模式,在Request和Response对象封装、从StandardWrapper到ServletConfig封装、从ApplicationContext到ServletContext封装中都有用到。
  • 观察者模式,Lifecycle、Servlet实例的创建、Session的管理、Container等。
  • 命令设计模式,Connector和Container组件之间有体现,Tomcat作为一个服务器,会接收到各种请求,如何分配和执行这些请求是必须的功能。
  • 责任链设计模式,在Tomcat中Container的容器中,各个组件间就是通过将请求一直传递,最终传给正确的Servlet。

第12章:Jetty的工作原理解析
1、Jetty的基本架构。P318(Jetty的核心由Server和Connector两个组件完成。整个Server组件是基于Handler容器工作的,它类似于Tomcat的Container容器。Connector组件则负责接收客户端的连接请求,并将请求分配给一个处理队列去执行)
2、Jetty是一个可扩展性强且非常灵活的应用服务器。它有一个基本的数据模型Handler,所有可以被扩展的组件都可以作为一个Handler添加到Server中,Jetty将帮你管理这些Handler。
3、基于NIO方式工作
4、与JBoss集成
5、与Tomcat的比较(架构比较、性能比较、特性比较)

第13章:Spring框架的设计理念与设计模式分析
1、核心设计理念。核心组件为Bean、Context、Core
Bean:最核心的组件,其实Spring就是面向Bean的编程(BOP),它的意义就像Object对OOP的意义一样。这种设计理念都是构建一个数据结构,然后根据这个数据结构设计它的生存环境,并让它在这个环境中按照一定的规律不停的运动,在它们的不停运动中设计一个系列与环境或者与其他个体完成信息交换。
Context:Bean包装的是Object,而Object必然有数据,如何给这些数据提供生存环境就是Context要解决的问题。Context就是要发现每个Bean之间的关系,为它们建立这种关系并且维护这种关系。所以Context就是一个Bean关系的集合,这个关系集合又叫Ioc容器,一旦建立这个Ioc容器,Spring就可以工作了。
Core:Core就是发现,建立和维护每个Bean之间的关系所需要的一系列工具,从这个角度来看,把Core组件叫做Util更让人理解。
2、核心组件内部类的层次关系
Bean:P337
Context:P339.ApplicationContext必须要完成的事情:①标识一个应用环境;②利用BeanFactory创建Bean对象;③保存对象关系表;④能够捕获各种事件;
Core:P340(Core包含了很多关键类,一个重要的组成部分就是定义了资源的访问方式。这种把所有资源都抽象成一个接口的方式很值得在以后的设计中拿来学习。)
3、Ioc是如何工作的。
4、Ioc容器提供了很多扩展点,我们可以通过实现这些扩展点来得到我们想要的个性结果,在Spring中有很多例子,AOP的实现就是Spring本身实现了扩展点达到了它想要的特性功能。
5、Spring中的设计模式
  • 代理模式:AOP应用
  • 策略模式:Spring中有很多地方使用策略模式,如Bean定义对象的创建及代理对象的创建。

第14章:Spring MVC的工作机制与设计模式
1、模板模式:模板模式被应该的很多,尤其是在框架的设计中,框架的作用在很大程度上就是为你创造一个方便的开发程序的模板,开发者只要实现模板中一些接口就能完成一个复杂的任务。模板的核心是,大的逻辑已经定义,你要做的就是实现一些具体步骤,不同的场景实现这些具体步骤的方法也会有所不同,从而模板的行为也会表现出具体的区别。
2、Spring MVC中的模板模式:
  • HandlerMapping有一个抽象类AbstractHandlerMapping,在这个抽象类中定义了一个完整的HandlerMapping的初始化和获取Handler对象的主体流程,但是又一个抽象方法getHandlerInternal留给子类去实现,只要子类实现了这个方法,那么整个getHandler的流程就完成了。
  • View的设计也使用了模板方法,View只定义了接口方法,AbstractView类实现了在View中定义的所有方法,并留有一个抽象方法renderMergedOutputModel给子类去实现。而AbstractJasperReportsView和AbstractTemplateView抽象类又进一步实现了AbstractView的抽象方法renderMergedOutputModel,并分别进一步细化出renderReport抽象方法和renderMergedTemplateModel给子类进一步实现。越往下,子类需要实现的功能越少,这个模板已经建立。

第15章:深入分析iBatis框架之系统架构与映射原理
1、sqlSessionFactory-->sqlSession-->sqlMap输入参数对象映射产生sql-->执行sql-->查询结果进行对象映射-->返回结果
2、iBatis要达到的目的就是把用户关心的和容易变化的数据放到配置文件中配置,方便用户管理,而把流程性的、固定不动的功能交给iBatis来实现。这样可以让用户操作数据库简单、方便,这也是iBatis的价值所在。

第18章:大浏览系统的静态化架构设计
1、静态系统通常具有的特征:
  • 一个页面对应的URL通常固定。不同的URL表示不同的内容,让返回的请求和URL相关,也就是通过URL能唯一标识一个页面。
  • 在页面中不能包含与浏览者相关的因素,这里所说的“不能包含”不包括JS动态生成的部分,也就是在页面中HTML代码不能明显的包含有与浏览器相关的DOM。例如不能含有用户的姓名、身份标识以及与Cookie相关的因素等。
  • 在页面中不包含时间因素。页面同样不能含有与时间(这里的时间不是指客户端浏览器中获取的实际,而是服务器端输出的时间)相关的因素,页面中的DOM结构不能随着时间的变化而变化。典型的案例如淘宝的秒杀中,到某个时间点就可以使用页面中的立即购买按钮,则这个判断的时间就是从服务器端获取的时间。
  • 页面中不包含地域因素。对页面中的地域因素很好立即,即从北京访问看到的页面要和上海访问看到的页面相同。淘宝上也有个例子,就是宝贝的运费在不同的地区可能不一样。如果做成静态化,则这个运费就不能直接反映在HTML代码中了。
  • 不能包含Cookie等私有数据。Cookie实际上主要是用来标识访问量信息的一个工具,如果在页面中含有这些私有数据,也不可能不包含上面这些因素了。所以要满足静态化,就不能包含Cookie等信息。
2、静态化的优点:
  • 改变了缓存方式。直接缓存HTTP连接而不是仅仅缓存数据,Web代理服务器根据请求URL直接取出对应的HTTP响应头和响应体直接返回,这个响应连HTTP都不用重新组装,同样,HTTP请求头也不一定需要解析,所以做到了获取数据最快。
  • 改变了缓存的地方。不是在Java层面做缓存,而是直接在Web服务层上做,所以屏蔽了Java层面的一些弱点(不擅长处理大量的连接请求,每个连接消耗的内存较多,Servlet容器解析HTTP较慢等),而Web服务器(如Nginx、Apache、Varnish)都擅长处理大并发的静态文件请求。
3、如何改造动态系统:
  • 动静分离
  • 动态内容结构化
  • 动态组装内容(服务器组装或AJAX请求组装)
4、几种静态化方案的设计与选择
  • 采用Nginx+Cache+Java结构的虚拟机单机部署
  • 采用Nginx+Cache+JAVA结构实体机单机部署
  • 统一Cache层
5、服务端静态化方案的演进:CDN化


猜你喜欢

转载自blog.csdn.net/key_next/article/details/79511472