Spring如何实现MVC-上篇
前言Spring应该是后端Java开发者使用最多框架,感觉大家对这个框架也很了解比如IOC和AOP这两个特性是最为熟悉,而且很多大佬都知道Spring是怎么初始化Spring的Bean从refresh()方法开始讲然后滔滔不绝能说好久。不得不说Spring这种低侵入的轻量化的框架受到大多开发者追捧。而且它DI做的真的真的很不错,比EJB好要用很多。
不过说了这么多,我上面那些都不是我这篇要写博客的重点。我打算说下关于Spring容器是如何在Web容器启动(tomcat/jetty)SpringMVC是怎么实现Servlet3.0的规范。我们平时都只和业务中的controller、service、dao打交道很多,但是这些是如何被Spring被启动并注入到Spring容器这个过程是很有意思的。不过现在都是使用SpringBoot。让我们今天考考古,挖挖坟。
这篇主要讲怎么通过传统的SpringMVC去创建一个webApplicationContext对象。
在聊SpringMVC之前我先说说Servlet,可以说Servlet是JavaWeb程序比较核心的东西,在没有出现SpringMV ...
MySQL中的binlog、redolog
前言对MySQL有些了解的人一定知道MySQL不是直接把数据直接写到数据表上,而是先写到日志上,在从日志信息同步到对应的数据库文件。所以MySQL中有很多关于数据存储的日志文件,当然也有很多MySQL运行时的日志,比如错误日志、查询日志、慢查询日志等等。我们这次主要想说一些关于MySQL存储数据的日志。比如二进制日志bin log和事务日志(InnoDB存储引擎)redo log这两种日志。
WAL机制WAL:(Write-Ahead Logging 预写日志),上面我们说MySQL存储到表数据前是把数据以日志形式记录下来。这种方式有好处就是可以提高部分MySQL性能,同时在备份和还原数据记录有可以有很多日志可以帮DBA更好的完成工作(crash recovery)。但是也有不好地方,就是会产生脏数据产生锁冲突,大量日志文件也占用了IO资源。下面我们详细说下WAL机制。(不过也不详细,毕竟不是DBA)
用户如果对数据库中的数据进行了修改,必须保证日志先于数据落盘。当日志落盘后,就可以给用户返回操作成功,并不需要保证当时对数据的修改也落盘。如果数据库在日志落盘前crash,那么相应的数据 ...
浅入浅出RocketMQ
前言MQ (Message queue) 即消息队列,简单来说就是你发送一个消息向队列里面,然后订阅这个队列的系统就会收到消息信息,内容就和你发出去的一样。这样的产品有很多比如RocketMQ,Kafka,ActiveMQ和RabbitMQ等等。使用MQ的主要作用就是解耦。举个例子,比如你的订单流程特别长,包括下单,支付,库存扣减,消息推送,发货,积分,优惠券,大数据同步等等,涉及好多系统。这些系统肯定都是相对独立的,如果把所有功能都做到一个系统肯定会把人作死。所以我们会使用分布式调用的方式去实现,但是后来你发现通过分布式这种同步调用会导致整个下单流程很长,而且时间也很长经常超时,特别是在一些活动的时候压力上来了订单系统创建时间更长了。为了解决这个问题我们帮同步的调用改成异步的调用就引用了MQ。(当然这只是举了一个例子)
RocketMQ是什么,他是由哪几部分组成的RocketMQ是一个分布式消息和流数据平台,具有低延迟、高性能、高可靠性、万亿级容量和灵活的可扩展性。RocketMQ是2012年阿里巴巴开源的第三代分布式消息中间件,2016年11月21日,阿里巴巴向Apache软件基金 ...
泛型
前言泛型这个词了解编程的人应该都和熟悉,一般强类型的语言都会有,参数类型比较明确。类似Java,C#,C++等语言都有泛型,而且他们都是编译类型或者半编译半解释型的语言。这从另外一个层面说明泛型只能生效在编译期,等到运行时久被擦除。我想熟悉Java的同学都知道我在说什么,估计之前都了解一个词叫类型擦除,而且在面向对象会经常使用,这个还会涉及多态的概念。
什么是泛型泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
作用:一些强类型程序语言支持泛型,其主要目的是加强类型安全及减少类转换的次数,但一些支持泛型的程序语言只能达到部分目的。
类型擦除Java 泛型的参数只可以代表类,不能代表个别对象。由于Java泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型,而且无法直接使用基本值类型 ...
Java的ClassLoader
前言ClassLoader是Java中很重要一个功能,我们都知道Java是个跨平台的语言,这个跨平台的语言是通过JVM去实现,Java通过编译器成class文件,在使用的时候通过ClassLoader去加载。而且很多框架喜欢使用ClassLoader来实现一些特定功能。比如热更新(通过替换新的ClassLoader装载新的class文件实现代码更新),Tomcat中防止重复jar的加载(Tomcat内置好ClassLoader加载器,指定了不同地方的jar包,防止一些类重复加载比如servlet的jar)等等功能。
初识ClassLoaderClassLoader:类加载器,Java是动态类加载(java 不是一次把所有类都加载进去所有类会很占内存,使用的时候加载,不用的时候卸载,用于把类加载到JVM当中,让JVM使用执行的。所以一般Java类加载器都会指定一些目录,比如我们在window系统中指定环境变量目录CLASSPATH=.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
三种类加载器BootStrapClassLoade、Extention ...
浅谈Redis底层-SkipList
前言这篇文章是上一篇SDS的后续,也是讲的Redis的底层数据结构。SDS是String的底层,这个次讲的是Zset(sorted set)的底层实现,跳表SkipList。SkipList是一种很好的数据结构。他的查找速度是O(logn)的时间复杂度。而且存储空间开销也还好,可以接受。简单点说SkipList就是一种通过关键节点(类似索引的方式)。将数据通过多层来快速划分和查找的过程。而且这个跳表好不用像树一样要经常的翻转。
SkipListSkipList: 跳表即跳跃链表。他的查找和插入时间复杂度是O(logn),优于数组O(n)插入和查找的时间复杂度。跳表实现快速查询时通过多层次链表做索引,然后通过不同层次节点大小来快速判断底层数据在那个范围存储,概率性跳过不需要查找的元素,来实现快速定位查找。跳表时个有层次的数据结构,它越上层的链表越稀疏(类似漏斗,越稀疏过滤元素越多),对比队列中的值,然后判断跳跃范围,通过层层跳跃找到最后的搜索元素。
跳表的最底层时存储所有的数据有序的链表,它的每个上层都是最底层的索引。层中元素i出现在索引层,也就是当前层的上一层的概率时p.(P值一般时1 ...
浅谈Redis底层-SDS
前言Redis我想大家都很熟悉,我们都会用Redis去做缓存。Redis常用的数据结构大家也都熟悉,Redis常用数据结构我想大家也都知道,除了最常用的String,List,Set,Hash,Zset,BitMap,HyperLogLog,Geo等等。之前我写过Redis基本数据结构的文章。不过Redis真正怎么通过C语言的程序设计去让这个Redis更快,更加高性能。可以简单的研究一下关于Redis底层的数据结构。
SDSSDS:(simple dynamic string)简单的动态字符串。动态字符串是一种由Redis提供的字符串的数据结构,他不是使用C语言自带的字符串。(C语言自带的字符串还是由一些问题,比如内存溢出,查找字符串的长度等等)。
SDS的简单定义
123456789typedef char *sdsstruct sdschar { // buf[] 中已使用的字节数 int len; // buf[] 中未使用的字节数 int free; // 字符数组,用于实际存储字符串内容 char buf[];}
这个 ...