随笔02
https实现原理最近看的一篇面试总结,原作者写的有一丢丢问题,下面这篇讲的很清楚
深入理解https
在此之前,需要了解对称加密和非对称加密的原理和效率对比
对称加密,就是加密和解密用的同一把密钥,加密和解密速度快
非对称加密,加密用公钥,解密用密钥,公钥是公开的,但在解密的时候只有用相应的密钥才能解密,加密和解密速度慢。
https解决的http的三大问题:
明文传输,裸奔
消息的完整性无法判断
通信身份可能被伪造
基于以上三大问题,讲下https在进行传输的时候是如何解决的:
C请求https域名,443端口,携带浏览器支持的hash算法和加密算法
S是有CA一对私钥和公钥,私钥是一定不能在网上直接传输的,所以把公钥和返回浏览器支持的hash算法和加密算法
C就要校验公钥的合法性,这个过程是浏览器内部的TSL完成,主要校验证数是否与域名匹配,是否到期,校验通过的话,就进入下一个步骤,没通过就会在C提示相应的信息
C随机生成一个X,通过公钥加密,传输给S,S进行私钥解密——唯一一次非对称加密
后面的信息传输都是对称加密,因为X这个就是对称加密的密钥,巧妙的通过C ...
随笔01
ArrayList和LinkedList区别对于这两种数据结构的基础比较,如,线程安全问题、底层结构,空间占用问题我就不多说了,网上很多文档写的很清楚了,这里我详细的讲下自己对ArrayList和LinkedList在数据的查询,增加,删除和修改上的性能差异:
要分析在三种情况下的差异,首先要清楚两种容器它的底层实现是什么,ArrayList底层是数组实现的,连续的地址内存空间,也就是带索引;LinkedList底层是双向链表,不是连续的内存空间,而且双向链表的每个节点都存放前驱,当前,后继节点信息。
查询:一般就两种查询,查询某索引的元素和查询某元素的索引,比如查询第N个索引下的元素,这个毫无疑问是ArrayList快,因为它底层是数组,支持快速随机访问,时间复杂度是O(1),LinkedList不是连续的,只能一个接着一个的去找,时间复杂度是O(n)。对于查询某元素的索引,两种容器就只能遍历了,效率是差不多的
插入,也分插入的位置,是头部,是中间,是末尾?此时ArrayList的连续的内存地址这个特点就变成劣势了,当插入到头部和中间部分,Arraylist就需要数组的copy或 ...
Redis必知必会
Redis绝对是当下非常火热的一个NoSql数据库,在之前的博客中,我已经讲到了springboot集成redis的使用,今天在这里分享下Redis常问面试题
1.为什么使用Redis?在项目中使用Redis,主要考虑两个角度:性能和并发。如果只是为了分布式锁这些其他功能,还有其他中间件 Zookpeer 等代替,并非一定要使用 Redis。
性能:
如下图所示,我们在碰到需要执行耗时特别久,且结果不频繁变动的 SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。
特别是在秒杀系统,在同一时间,几乎所有人都在点,都在下单,执行的是同一操作——向数据库查数据。
根据交互效果的不同,响应时间没有固定标准。在理想状态下,我们的页面跳转需要在瞬间解决,对于页内操作则需要在刹那间解决。
并发:
如下图所示,在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用 Redis 做一个缓冲操作,让请求先访问到 Redis,而不是直接访问数据库。
2.Redis为什么快?Redis的速度非常的快,单机的Redis就可以支持每秒 ...
Spring必知必会
Spring中用到了哪些设计模式?单例模式Spring中的Bean默认情况下都是单例的。bean被声明为单例的时候,在处理多次请求的时候在Spring容器里只实例化出一个bean,后续的请求都公用这个对象,这个对象会保存在一个map里面。当有请求来的时候会先从缓存(map)里查看有没有,有的话直接使用这个对象,没有的话才实例化一个新的对象,所以这是个单例的。但是对于原型(prototype)bean来说当每次请求来的时候直接实例化新的bean,没有缓存以及从缓存查的过程。
所以单例的bean只有第一次创建新的bean后面就会复用bean,所以不会频繁创建对象。
原型的bean每次都会新创建
单例bean的优势:
减少了新生成实例的消耗 新生成实例消耗包括两方面,首先,Spring会通过反射或者cglib来生成bean实例这都是耗性能的操作,其次给对象分配内存也会涉及复杂算法
减少jvm垃圾回收 由于不会给每个请求都新生成bean实例,所以自然回收的对象少了
可以快速获取到bean 因为单例的获取bean操作除了第一次生成之外其余的都是从缓存里获取的所以很快
单例bean的劣 ...
Java多线程必知必会
进程和线程的联系和区别进程:是程序在执行中进行资源分配和调度的基本单位
线程: 是进程的进一步划分,是进程的一个执行体,更小的独立运行的基本单位,亦称轻量级线程
举个栗子:
我们在使用QQ的时候假设是一个进程,那我们使用QQ的发短信,发文件,发说说等功能就可以说是线程。
进程和线程的区别:
进程是独立的地址空间,但同一个进程内的线程共享本进程的地址空间
同一进程的线程共享资源比如CPU,内存等等,但进程之间是相互独立的
一个进程崩溃后,在保护模式下不会对其他进程产生影响
一个线程崩溃整个进程都死掉,所以多进程要比多线程要健壮
进程可以独立运行,且每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口
线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程的执行控制,线程是处理器调度的基本单位,但进程不是
两者都支持并发执行。进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。如果同时要求进行并且又要共享某些变量的并发操作,就只能用线程(进程之间是想独立的)
线程的生命周期内容摘录自:https://zhuanlan.zhihu ...
Mysql必知必会
介绍MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。
mysql架构图
myisam和innodbmyisam引擎是5.1版本之前的默认引擎,有如下特点:
不支持事务
只支持表级锁定 —>数据更新时锁定整个表,就说说对一个数据进行操作就会锁定整个表,其他人不能同时操作这个表,实现容易但并发效率低。
只会缓存索引 —> myisam可以通过key_buffer_size的值来提高缓存索引,以大大提高访问性能减少磁盘IO,但是这个缓存区只会缓存索引,而不会缓存数据。
读取速度较快,占用资源较少
不支持外键约束,但只是全文索引
对于count(*)查询来说MyISAM更有优势,因为其保存了行数
使用场景:
1.不需要支持事务的业务
2.读数据比较多的应用,读写都频繁的场景不适应(表级锁定)
3.独写并发访问较低的业务
innodb
支持事务,支持4个事务的隔离级别,支持多版本读
默认行级锁(更新时 ...
八大排序算法(下)
归并排序归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该方法采用经典的分治策略(分治法将问题分成一些小的问题然后递归求解,而治的阶段则将分的阶段得到的各个答案拼接在一起,即为分而治之)。
实现思想
具体步骤
代码实现
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475//分+合方法public static void mergeSort(int[] arr, int left, int right, int[] temp) { if(left < right) { int mid = (left + right) / 2; //中间索引 //向左递归进行分解 mergeSort(arr, left, mid, temp); //向右递归进行分解 ...
单例模式的多种实现方式
单例模式,顾名思义就是只有一个实例,并且它自己负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。下面我们来看下有哪几种实现方式吧。
单例模式分饿汉式和懒汉式,下面介绍下两种的具体写法:
饿汉式饿汉式就是在类加载的时候就已经创建实例,不管你用没用到,都创建。
好处:线程安全
坏处:浪费内存空间
123456789101112public class Hungry { //构造器私有 private Hungry() { } private static Hungry hungry = new Hungry(); public static Hungry getInstance(){ return hungry; }}
我们可以简单的测试下,它在多线程环境下是否会产生线程安全问题
1234567891011121314public class TestHungry { public static void main ...
HashMap源码分析
1.HashMap介绍1.1 HashMap底层存储结构
HashMap最早出现在JDK1.2中,底层基于散列算法实现。HashMap 允许 null 键和 null 值,是非线程安全类,在多线程环境下可能会存在问题。
1.8版本的HashMap底层存储结构:
数组+链表+红黑树
1.2 HashMap类的定义先来看看HashMap类的定义:
12public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {
从中我们可以了解到:
HashMap<K,V>:HashMap是以key-value形式存储数据的。
extends AbstractMap<K,V>:继承了AbstractMap,大大减少了实现Map接口时需要的工作量。
implements Map<K,V>:实现了Map,提供了所有可选的Map操作。
implements Cloneable:表 ...
浅谈==和equals
1.运行时数据区
粗略的讲下Java的内存结构,要想深入的讲还需要把JVM的知识拿来,但我们现在的核心是比较==和equals的区别以及常见数据类型在取等和调用equals时产生的结果和原因。
如上图,很重要的就是栈,堆,方法区,下面简单介绍他们的作用:
栈(stack):位于通用RAM中,但通过它的“栈指针”可以从处理器哪里获得支持。栈指针若向下移动,则分配新的内存;若向上移动,则释放那些 内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时候,JAVA编译器必须知道存储在栈内所有数据的确切大小和生命周期,因为它必须生成 相应的代码,以便上下移动栈指针。这一约束限制了程序的灵活性,所以虽然某些JAVA数据存储在栈中——特别是对象引用,但是JAVA对象不存储其中。
– 存放基本类型的变量数据和对象,数组的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中)。
堆(heap):一种通用性的内存池(也存在于RAM中),用于存放所以的JAVA对象。堆不同于栈的好处是:编译器不需要知道要从堆里分配多少存储区 域,也不必知道存储的 ...