数据结构-8-暴力递归
Hanoi
1234567891011121314151617public void process(int index, String from, String to, String other) { if (index == 1) { // base case 如果仅剩一个盘子,则直接放到to位置 System.out.println("将" + index + "从" + from + "移动到" + to); } else { // i - 1, from -> other process(index - 1, from, other, to); // i, fom -> to System.out.println("将" + index + "从" + from + "移动到" + to); //i - 1, o ...
JUC-2-CompletableFuture
Future接口
Future接口(FutureTask实现类)提供一种异步并行计算的功能(获取异步任务的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕)
如果主线程需要执行耗时的计算任务,可以通过future把这任务放到异步线程中执行,主线程继续处理其他任务或者先行结束,再通过future获取计算结果。它可以为主线程开一个分支任务,专门为主线程处理耗时和费力的复杂业务
Future接口常用实现类FutureTask异步任务
多线程
有返回值
异步任务
优点:future + 线程池异步多线程任务配合,能显著提高程序的执行效率
缺点:
get()阻塞:一旦调用get()方法求结果,如果计算没有完成容易导致程序阻塞;
isDone轮询:
轮询的方式会耗费CPU资源,而且不一定能及时得到计算结果
如果想要异步获取结果,通常会以轮询的方式去获取结果,尽量不要阻塞
结论:Future对于结果的获取不是很友好,只能通过阻塞或轮询的方式得到任务的结果
CompletableFuture对Future的改进
回顾Future
get()方法在Future ...
JUC-1-基础回顾
基础知识
并发(concurrent)
同一个实体上的的多个事件
一台处理器上同时处理多个任务
并行(parallel)
在不同实体上的多个事件
多台处理器上同时处理多任务
进程
在系统中运行的一个应用程序就是一个进程,每一个进程都有它自己的内存空间和系统资源
线程
轻量级进程,在同一个进程内会有一个或多个线程,是大多数操作系统进行时序调度的基本单元
管程
Monitor(平时所说的锁),一种同步机制,保证(同一时间)只有一个线程可以访问被保护的数据和代码。JVM中同步是基于进入和退出监视器对象(Monitor,管程对象)来实现道德,每个对象实例都会有一个Monitor对象。Monitor对象会和Java对象一同创建并销毁,底层由C++实现
用户线程
一般情况下不做特别说明配置,默认都是用户线程。用户线程是系统的工作线程,它会完成这个程序需要完成的业务操作
守护线程
守护是一种特殊的线程为其它线程服务,在后台默默地完成一些系统性的服务(比如垃圾回收线程)
守护线程作为一个服务线程,没有服务对象就没有必要继续运行。如果用户线程全部结束,意味着程序需要 ...
MySQL高级篇-5-存储引擎
查看存储引擎
查看存储引擎
1show engines;
设置系统默认的存储引擎
查看默认的存储引擎
123show variables like '%storage_engine%';-- 或SELECT @@default_storage_engine;
修改默认的存储引擎
如果在创建表的语句中没有显式指定表的存储引擎的话,那就会默认使用InnoDB作为表的存储引擎。 如果我们想改变表的默认存储引擎的话,可以这样写启动服务器的命令行
1SET DEFAULT_STORAGE_ENGINE=MyISAM;
或者修改my.cnf文件:
1default-storage-engine=MyISAM
12# 重启服务systemctl restart mysqld.service
设置表的存储引擎存储引擎是负责对表中的数据进行提取和写入工作的,可以为 不同的表设置不同的存储引擎 ,不同的表可以有不同的物理存储结构、不同的提取和写入方式。
创建表时指定存储引擎创建表的语句都没有指定表的存储引擎,那就会使用默认的存储引擎 InnoDB 。如果我们 ...
MySQL高级篇-4-逻辑架构
逻辑架构剖析服务器处理客户端请求以查询请求为例剖析服务器进程对客户端进程发送的请求做出怎样的处理得到最后结果
第1层:连接层 系统(客户端)访问 MySQL 服务器前,做的第一件事就是建立 TCP 连接。经过三次握手建立连接成功后, MySQL 服务器对 TCP 传输过来的账号密码做身份认证、权限获取。
用户名或密码不对,会收到一个Access denied for user错误,客户端程序结束执行
用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑,都将依 赖于此时读到的权限
TCP 连接收到请求后,必须要分配给一个线程专门与这个客户端的交互。所以还会有个线程池,去走后 面的流程。每一个连接从线程池中获取线程,省去了创建和销毁线程的开销。
第2层:服务层
SQL Interface:SQL接口
接收用户的SQL命令,并且返回用户需要查询的结果。比如SELECT … FROM就是调用SQL
MySQL支持DML(数据操作语言)、DDL(数据定义语言)、存储过程、视图、触发器、自定 义函数等多种SQL语言接口
Pars ...
Redis-6-原理篇-网络模型
用户空间和内核态空间进程的寻址空间划分成两部分:内核空间、用户空间
应用程序也好,还是内核空间也好,都是没有办法直接去物理内存的,而是通过分配一些虚拟内存映射到物理内存中,内核和应用程序去访问虚拟内存时,就需要一个虚拟地址,地址是一个无符号的整数
比如一个32位的操作系统,他的带宽就是32,他的虚拟地址就是2的32次方,也就是说他寻址的范围就是0~2的32次方, 这片寻址空间对应的就是2的32个字节,就是4GB,这个4GB,会有3个GB分给用户空间,会有1GB给内核系统
在linux中,他们权限分成两个等级,0和3,用户空间只能执行受限的命令(Ring3),而且不能直接调用系统资源,必须通过内核提供的接口来访问内核空间可以执行特权命令(Ring0),调用一切系统资源,所以一般情况下,用户的操作是运行在用户空间,而内核运行的数据是在内核空间的,而有的情况下,一个应用程序需要去调用一些特权资源,去调用一些内核空间的操作,所以此时他俩需要在用户态和内核态之间进行切换。
比如,Linux系统为了提高IO效率,会在用户空间和内核空间都加入缓冲区:
写数据时,要把用户缓冲数据拷贝到内核缓冲区,然 ...









