不断的学习,我们才能不断的前进
一个好的程序员是那种过单行线马路都要往两边看的人
JAVA源码

ForkJoin

ForkJoin ForkJoin 是一个并行计算框架,以支持分治任务模型, Fork 对应任务分解,Join对应任何合并。PS:大任务 拆分成小任务,最后在合并结果 ForkJoinPool ForkJoinPoll 跟 ThreadPoolExecuto类似,都是继承于AbstractExecutorService类。 但是 ForkJoinPool 有多个任务队列,而且这个任务队列是双向的,内部使用的是“工作窃取”算法,就是当前工作线程 完成工作队列里面的任务后,可以帮助其他线程完成任务队列里面的任务,任务类是ForkJoinTask。 public class ForkJoinPool extends AbstractExecutorService { public

  • Jinhanlai
4 min read
JAVA源码

Java 注解原理分析

Java 注解 编译时注解、运行时注解 在定义注解时,在每个注解接口上面需要定义注解的生命周期: @Retention(RetentionPolicy.RUNTIME) 表示运行时注解,在运行时可以通过反射获取相关信息。 @Retention(RetentionPolicy.CLASS) 表示编译时注解,会由编译器记录在class 文件中,但是在运行时不会保留。 @Retention(RetentionPolicy.SOURCE) 表示注解的信息会被编译器抛弃,不会留在class文件中 运行时注解(@Autowired)与编译时注解(@Override、@Deprecated)的区别? 运行时注解保留到运行时,可在运行时访问。而编译时注解保留到编译时,运行时无法访问。

  • Jinhanlai
4 min read
面试准备

秋招面经

阿里面经 蚂蚁一面 自我介绍 介绍实习,介绍秒杀项目 怎么设计和考虑秒杀项目的架构的?取消支付订单是怎么考虑的?先写缓存还是先写数据库?会存在什么问题? 修改数据库库存的时候使用什么锁?乐观锁还是悲观锁? String 对象是怎么进行回收的? 密码的话用字符串存储会出现什么问题?PS:字符串常量池里面存在密码的副本,所以会存在密码泄露 ArrayList、LinkedList、vector?删除和增加用哪一种?查询用哪一种?vector呢?如何设计实现一个线程安全的LinkedList?PS:链表的话考虑读写锁?CAS操作也可以,但是无法保证有序性 一个java文件里面有私有实例变量、静态变量、静态方法、静态代码块,他们分别存在什么地方?

  • Jinhanlai
21 min read
中间件

消息队列

消息队列之 RabbitMQ RabbitMQ 消息队列默认采用FIFO的消息,如果需要提前处理某些消息就可以设置成优先级队列,根据优先级消费消息。 RabbitMQ 的消息是可以进行持久化的,对于交换机(exchange)与队列(queue)的持久化只需要将durable属性设置为true即可,当重启RabbitMQ服务后,交换机和队列都会恢复,但是当只有队列的durable属性设置为true时,重启后会造成消息丢失。 专业术语 通道(Channel):一个管道连接,是tcp连接内的连接(broker),使用现有的TCP连接进行数据传输; 交换器(Exchange):消息路由,生产者发送的消息并不是直接发送到队列中而是先到指定的路由中,然后由路由根据路由key绑定的队列发送到指定队列中; 绑定(Binding):建立路由和队列容器的绑定关系; 消息(

  • Jinhanlai
13 min read
面试准备

Java 面试之--开放性问题

Java 面试之--开放性问题 服务器宕机,如何排查问题? 服务器宕机可以从以下几个方面考虑 服务器性能:服务器性能原因是普遍的故障因素,当数据处理能力更不上的时候,是很容易发生宕机故障。 资源耗尽:当服务器的资源发生耗尽情况的时候,也会出现宕机的故障。例如受到了网络攻击,访客的暴增,高负载等情况就是主要的原因。 服务器内部系统错误:服务器内部系统错误也是发生宕机的主要因素,例如链接中断,无法链接的情况。 排查问题 控制台使用Jconsole 连接到本地服务器或者远程服务器,查看内存、线程的使用情况; 使用jps 或者 ps -ef | grep java 查看java线程PID; 然后使用jstack 查看并分析

  • Jinhanlai
10 min read
Java

Java 面试之--Spring IOC

Spring IOC 初始化IOC的流程: prepareRefresh: 准备工作(记录容器的启动时间、标记状态等)--> obtainFreshBeanFactory: 解析配置文件获取初始化的beanDefinition并存入到容器map里面---> prepareBeanFactory: 设置BeanFactory的类加载器并注册一些特殊的bean(enviorment、systemProperties、systemEnvironment)---> postProcessBeanFactory: 注册bean工厂后置处理器----> invokeBeanFactoryPostProcessors: 激活并处理bean后置工厂处理器,可以访问并修改beanDefinition ----> registerBeanPostProcessors: 向IOC容器注册bean后置处理器, 获取所有的BeanPostProcessors并存放到容器里面---> 执行初始化(在初始化之前

  • Jinhanlai
15 min read
数据结构

算法之美--最短路径与最小生成树

最短路径 从某个源点到其余各顶点 Dijkstra: 从某个源点 到 其余各点的最短路径:Dijkstra 算法 主要思想:以起始点为中心向外层层扩展,每次选择当前结点距离最短的那个结点,并重新计算更新距离,再次选择最短的。 采用的是邻接矩阵来表示图,主要步骤如下: 前提: 需要一个数组distance来记录到其余顶点之间的最短路径; 需要一个boolean数组visited来判断到该顶点是否已经找到最短路径 需要一个二维数组path来判断到该顶点的最短路径 需要经过的顶点; 计算起始顶点V0,到其余各个顶点之间的距离 选择计算出来最短的距离的顶点,Vi。 以Vi为起始顶点,计算到其他顶点之间的距离,并更新记录距离的表(选择最短距离) 和 path 路径表。 重复步骤4,知道所有顶点都被访问

  • Jinhanlai
10 min read
Java

java 面试之--SpringBoot

SpringBoot SpringBoot 自动装配 Spring Boot的自动装配是通过@EnableAutoConfiguration 实现的,可以将启动类下所有的component组件注册到容器中,通过 SpringFactoriesLoader 最终加载外部jar包下面的META-INF/spring.factories中的自动配置类实现自动装配,自动配置类其实就是通过@Conditional按需加载的配置类,想要其生效必须引入spring-boot-starter-xxx包实现起步依赖。 比如对于database属性,必须有username、password属性,如果没有则会连接不上数据源。在这种情况如果还进行数据源的装配,则会抛出异常,所以希望不装配数据源。使用Conditional注解,传入实现Condition接口,重写matches匹配的方法,返回true则进行装配,false则不装配。 @Target(ElementType.TYPE) @Retention(RetentionPolicy.

  • Jinhanlai
2 min read
面试准备

java 面试之---Spring

Spring IOC Spring Ioc指的是控制反转( 就是依赖倒置原则的一种代码设计的思路,具体采用的方法就是依赖注入),就是把原本在程序中手动创建对象的控制权,交给IOC容器来控制,IOC容器负责对象的创建、赋值和管理,降低了系统的耦合度。只需要知道对象的名称即可,通过名字获取Bean对象。可以通过XML配置 和 注解两种方式来实现。 IoC 容器实际上就是个Map,存放各种对象。 IOC初始化过程: IOC源码分析: 主要过程: 解析提供的配置文件路径 准备工作:记录容器的启动时间、标记状态 obtainFreshBeanFactory 会初始化 BeanFactory、加载 Bean、注册 Bean;

  • Jinhanlai
32 min read
面试准备

Mybatis

Mybatis 1. 什么是Mybatis? Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。 MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java

  • Jinhanlai
30 min read
面试准备

Java 面试之--ConcurrentHashMap

ConcurrentHashMap ConcurrentHashMap是线程安全的Map结构 底层的数据结构 底层的数据结构采用数组+链表+红黑树的结构,其中Node结构里面有hash、key、value、next指针,当发生hash冲突的时候,需要用链地址法来解决冲突。当链表长度大于8且容量大于64的时候,会转换成红黑树结构,TreeNode结点继承于Node 结点,里面有parent、left、right指针,内部也维护了Node结点的next指针,因为在进行扩容迁移的时候,需要使用到这个next指针,把链表或者红黑树转换成高低位两个链表。 除此之外还有sizeCtrl,大于0表示用来控制扩容的阈值,-1表示并发情况下的初始化中(值为-1),小于0 但不等于-1 表示扩容中。 transferIndex 用来记录扩容时,旧表当前扩容的位置

  • Jinhanlai
16 min read
面试准备

Java 关键字--Volatile与Synchronized

Volatile volatile 关键字在并发编程中保证了共享变量的“可见性”。可见性是指当一个线程修改一个共享变量时,另外一个线程能够读到这个修改的值。Synchronized 关键字也可以保证可见性(使用锁),但是volatile 变量修饰符的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。 CPU术语定义 术语 英文单词 描述 内存屏障 memory barriers 一组处理器指令,用于实现对内存操作的顺序限制 缓冲行 cache line CPU高速缓存中可以分配的最小存储单元。处理器填写缓存行时会加重整个缓存行 原子操作 atomic operations 不可中断的一个或一系列操作 缓存行填充 cache line

  • Jinhanlai
22 min read
面试准备

Java 面试之--BIO/NIO/AIO

BIO/NIO Linux 提供了五种IO模型:阻塞IO、非阻塞IO、IO复用模型、信号驱动IO模型、异步IO模型 前导知识 什么是中断 当CPU接受到中断请求时,会暂停正在运行的程序并保留程序上下文,转而执行一个称为中断处理器或中断服务程序的特定程序,服务完毕后再返回去继续运行被暂时中断的程序。 软中断与硬中断 硬件中断是由外设引发的, 软中断是执行中断指令产生的。 硬件中断是由与系统相连的外设(比如网卡 硬盘 键盘等)自动产生的,主要是用来通知操作系统系统外设状态的变化。 每个设备或设备集都有他自己的IRQ(中断请求), 基于IRQ, CPU可以将相应的请求分发到相应的硬件驱动上(注: 硬件驱动通常是内核中的一个子程序, 而不是一个独立的进程). 比如当网卡受到一个数据包的时候, 就会发出一个中断)

  • Jinhanlai
17 min read
面试准备

Java 面试之--线程池

线程池 FutureTask的作用? FutureTask对象可以获取到线程执行的结果。FutureTask 继承于future接口和Runnable接口,future的get方法可以获得 线程执行的结果,而使用线程池的时候,只能传入Runnable接口的对象,而Runnable接口不能获得线程的返回值,所以需要使用callable接口,封装一个FutureTask对象,然后返回给外部线程一个Future句柄的get 方法来获取结果,而get 方法会阻塞获取结果的线程,直到任务完成。 FutureTask的初始化可以传入runnable接口 和 callable接口,如果传入runnable接口的话使用一个RunnableAdapter适配器变成callable接口(执行call方法,实际上执行的是runnable的run方法),返回值是null,在业务层面的FutureTask.get就会拿到一个null 值。 FutureTask的get操作会阻塞获取任务结果的线程,那么怎么唤醒这些线程呢? FutureTask的任务状态有NEW(表示新建,还没开始处理)、COMPLETING(

  • Jinhanlai
6 min read
面试准备

Java 源码解析之--ThreadPoolExecutor

ThreadPoolExecutor 使用线程池的目的是: 降低资源消耗:避免重复的创建和销毁线程造成的消耗。 提高响应速度:当任务到达后,任务可以不需要等到线程创建就能立即执行。 提供对线程的可管理性:提供对线程的统一分配、调优和监控。 核心参数 7大核心参数:核心线程池大小、最大线程池大小、空闲线程等待工作的超时时间、时间单元、线程工厂、阻塞队列 4大拒绝策略:拒绝任务并抛出异常(AbortPolicy,默认)、拒绝任务不抛出异常(DiscardPolicy)、和最早的任务竞争(DiscardOldestPolicy)、由当前线程执行任务(CallerRunsPolicy)。 Worker表示工作中的任务,继承于AQS模版, Worker初始化的时候会自己创建线程工厂。 线程池的状态:RUNNING表示可以正常接受任务并处理阻塞队列中任务、

  • Jinhanlai
7 min read
面试准备

Java 面试之--ThreadLocal

ThreadLocal 数据结构 ThreadLocal 是线程变量,要在<>里面指定变量的类型,作为ThreadLocalMap的value类型,ThreadLocalMap的key 是ThreadLocal类型,其中key是弱引用,value是强引用,所以每次使用完毕之后要使用remove,手动清除。 ThreadLocalMap 是ThreadLocal的静态内部类,在Thread 类里面有一个字段threadlocals,指向ThreadLocal.ThreadLocalMap。 所以每一个线程都有一个ThreadLocalMap,Thread.threadLocals获取这个map,每个线程都有自己的Thread类。 ThreadLocalMap采用的是懒初始化,只有在第一次set、get的时候才去初始化,get的时候存入的变量是null。 public class ThreadLocal<

  • Jinhanlai
8 min read
JAVA源码

Java源码解析之--FutureTask

FutureTask 使用线程池的时候,只能传入Runnable接口的对象,而Runnable接口不能获得线程的返回值,所以需要使用callable接口,所以封装一个FutureTask对象,FutureTask继承与Runnable接口和Future接口,future接口的get方法可以获取到返回值。 FutureTask的初始化可以传入runnable接口 和 callable接口,如果传入runnable接口的话使用一个RunnableAdapter适配器变成callable接口(执行call方法,实际上执行的是runnable的run方法)。 FutureTask 统一了 Runnnable 和 Callable,方便了我们后续对线程池的使用. FutureTask对象内部维护了线程的状态、callable对象、outcome输出结果,WaitNode等待队列。 FutureTask 中等待任务返回结果的队列,都会进行等待队列里面,是一个单向队列,队列中每个结点都是WaitNode。 这个队列被当成线程安全的栈来使用的,出栈和入栈使用CAS来保证线程安全。 public class

  • Jinhanlai
6 min read
面试准备

Java 面试之--HashMap

HashMap 面试题 讲讲Hash算法? Hash算法就是将任意长度的输入,映射到固定长度的输出。可能会存在Hash冲突,比如10个元素,映射到长度为9的hash表里面,一定有一个元素会冲突,解决方案有拉链法、开放地址法。 好的Hash算法应该考虑哪些内容? 应该考虑,分布要尽量的均匀、尽可能的避免hash冲突、通过结果不能反推回原先的值、一点小的变动也会得到不同的结果、效率要高效,长的文本也很快计算出结果。 HashMap的数据结构? 在Jdk1.8里面,HashMap采用的是数组+链表+红黑树的结构,每个结点是用Node表示,Node里面有key,value,next指针,hashcode值。当Hash冲突的时候采用的是拉链法。 还有TreeNode 表示红黑树结点,

  • Jinhanlai
6 min read
数据结构

算法之美--单调栈

单调栈 单调递增栈:单调递增栈就是从栈底到栈顶数据是从大到小 单调递减栈:单调递减栈就是从栈底到栈顶数据是从小到大 伪代码 //此处一般需要给数组最后添加结束标志符,具体下面例题会有详细讲解 // 不加的话需要额外处理 for (遍历这个数组) { if (栈空 || 栈顶元素大于等于当前比较元素) { 入栈; } else { while (栈不为空 && 栈顶元素小于当前元素) { 栈顶元素出栈; 更新结果; } 当前数据入栈; } } LeetCode题集 接雨水 柱状图中的最大矩形 132模式 下一个更大的数I 下一个更大的数II 下一个更大的数III

  • Jinhanlai
1 min read
面试准备

Java源码解析--Semaphore

Semaphore Semaphore信号量,用于控制并发访问共享资源的线程数量,是基于AQS模板实现的。主要操作包括acquire() 获取一个许可、release() 释放一个许可。 初始化 Semaphore默认是非公平锁的机制,可以通过传入参数实现公平锁。 public Semaphore(int permits) { sync = new NonfairSync(permits); } public Semaphore(int permits, boolean fair) { sync = fair ? new FairSync(permits) : new NonfairSync(permits)

  • Jinhanlai
4 min read
Java

Java源码解析---ReentrantLock

Java源码解析---ReentrantLock与AQS AQS概述 AQS抽象队列同步器,是实现锁的一个框架,内部定义了很多锁相关的方法。AQS内部维护了一个代表共享资源的状态变量volatile int state和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列)。 AQS 通过提供 state 及 FIFO 队列的管理,为我们提供了一套通用的实现锁的底层方法. 状态变量state state 初始化 0,在多线程条件下,线程要执行临界区的代码,必须首先获取 state,某个线程获取成功之后, state 加 1,其他线程再获取的话由于共享资源已被占用,所以会到 FIFO 等待队列去等待,等占有

  • Jinhanlai
17 min read
面试准备

数据结构-红黑树

数据结构面试 讲讲平衡二叉树、红黑树、B+树、B-树? 平衡二叉树 结点的左右子树高度不差不超过1 结点的左右子树也是平衡二叉树 红黑树的性质 节点是红色或黑色。 根节点是黑色。 每个叶子节点都是黑色的空节点(NIL节点)。 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点) 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。 红黑树在插入或者删除结点时,会进行变色或者旋转来满足条件。 平衡二叉树与红黑树 平衡二叉树比红黑树更加平衡,但AVL树在插入和删除的时候也会存在大量的旋转操作 插入删除比较多的时候选择红黑树;查找比较多的时候选择平衡二叉树。 红黑树没有严格要求,左右孩子高度之差小于1。 B-树/B树 是一种多路搜索树(并不是二叉的),每个结点的里面包含多个元素: 定义任意非叶子结点最多只有M个儿子;且M&

  • Jinhanlai
9 min read
面试准备

算法之美--KMP

KMP 有两个字符串,即pattern和value串,从value串里面匹配是否存在pattern串。 双指针 从主串的第一个字符起与子串的第一个字符进行比较,若相等,则继续逐对字符进行后续的比较;若不相等,则从主串第二个字符起与子串的第一个字符重新比较,以此类推,直到子串中每个字符依次和主串中的一个连续的字符序列相等为止,此时称为匹配成功。 public boolean doublePoint(String str, String pattern){ int n=str.length(),m=pattern.length(); int i=0,j=0; while

  • Jinhanlai
2 min read
面试准备

计算机网络

计算机网络 OSI七层协议与TCP5层协议? OSI七层协议从上到下是:应用层、表示层、会话层、运输层、网络层、链路层、物理层。 TCP五层协议从上到下是:应用层、运输层、网络层、链路层、物理层。( 没有表示层和会话层)。 应用层:应用层是 OSI 标准模型的最顶层,是直接为应用进程提供服务的。其作用是在实现多个系统应用进程相互通信的同时,完成一系列业务处理所需的服务。包括文件传输FTP、电子邮件SMTP、远程登录Telnet和远端接口调用等协议。 表示层: 表示层向上对应用进程服务,向下接收会话层提供的服务,表示层的主要作用就是将设备的固有数据格式转换为网络标准传输格式。 会话层:会话层位于

  • Jinhanlai
63 min read
面试准备

操作系统

操作系统 1. 进程、线程、协程的区别是什么?进程和线程的通信方式? 进程 进程的本质是正在执行的一个程序实例,包括程序计数器、寄存器和变量当前的值。与每个进程相关的是地址空间,每启动一个进程,系统都会为其分配地址空间,建立数据表来维护代码段、PCB(进程控制快)和数据段。进程基本上是容纳运行一个程序所需要所有信息的容器。 PCB 包括:进程标识符、进程调度信息(优先级、进程的状态)、进程状态信息(堆栈信息、寄存器信息) 地址空间是虚拟内存,通过页表来记录虚拟内存到物理内存直接的映射关系 僵尸进程 僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,

  • Jinhanlai
39 min read
redis

Redis数据结构与对象

1. 简单动态字符串(SDS) Redis 没有使用C语言的字符串,而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型, 并将 SDS 用作 Redis 的默认字符串表示。 在Redis里面C语言的字符串,只会用在不需要对字符串修改的地方,比如打印日志。 SDS 除了用来保存字符串的值外,还可以用做缓冲区:AOF 持久化模块中的 AOF 缓冲区, 以及客户端状态中的输入缓冲区, 都是由 SDS 实现的。 1.1 SDS

  • Jinhanlai
32 min read
redis

Redis

Redis概述 Redis是基于内存的高性能Key-Value数据库,是非关系型数据库(NoSQL),它主要是基于内存的数据库,并提供一定的持久化功能,并且支持多种数据结构。 Redis的特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 Redis支持数据的备份,即master-slave模式的数据备份。 redis 是单线程的,是基于内存的操作,CPU不是redis的瓶颈,redis的瓶颈是根据机器的内存和网络带宽。 redis是将所有的数据全部放在内存中的,所以使用单线程效率最高,多线程会CPU上下切换,会耗时; 对于内存的系统来说,没有上下文切换,多次读写都是在一个cpu里面,也就是单线程就是效率最高的。 redis默认有16个数据库,可以把数据存储在不同的数据库中,

  • Jinhanlai
46 min read
mysql

Mysql索引

1. Mysql索引 索引是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,特别是当表中的数据量越来越大的时候。 索引是在存储引擎层实现的而不是服务器层。 1.1 索引基础 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。 索引可以包含一个或多个列的值,如果索引包含多个列,那么列的顺序也十分重要,因为Mysql只能高效地使用索引的最左前缀列。 1.1.1 索引的类型 索引可以有很多种类型,为不同的场景使用不同的类型,在Mysql中索引是在存储引擎而不是在服务器层实现的。 B+Tree索引 B+树的非叶节点不存储数据,只存储索引和指针。B+

  • Jinhanlai
15 min read
redis

Redis 面试

Redis 面试题 Redis采用的是基于内存的,采用的是单进程单线程模型的 KV 数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。Redis的特点有: 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。它的,数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1); 数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的; 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗; 使用I/O多路复用模型,非阻塞IO; 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,

  • Jinhanlai
35 min read
mysql

Mysql面试

Mysql面试 InnoDB 内存结构和磁盘结构 InnnoDB 的数据都是放在磁盘上的,InnoDB 操作数据有一个最小的逻辑单位,叫做页(索引页和数据页)。我们对于数据的操作,不是每次都直接操作磁盘,因为磁盘的速度太慢了。InnoDB 使用了一种缓冲池的技术,也就是把磁盘读到的页放到一块内存区域里面。这个内存区域就叫 Buffer Pool。 DML修改数据的时候,先修改缓冲池里面的页。当内存的数据页和磁盘数据不一致的时候,我们把它叫做脏页。InnoDB 里面有专门的后台线程把 Buffer Pool 的数据写入到磁盘,每隔一段时间就一次性地把多个修改写入磁盘,这个动作就叫做刷脏。 InnoDB 内存结构 InnoDB 内存结构有4个部分部分:

  • Jinhanlai
79 min read
Java

JVM

JVM JVM内存结构 本小节讲解了虚拟机里面内存是如何划分的,以及堆里面的对象分配、布局和访问的过程。 运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。不同的区域有不同的用途、以及创建和销毁时间。如下图所示,JVM管理的内存包括以下几个方面: 灰色是所有线程共享的数据区,白色是线程隔离的数据区 程序计数器 程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。在JVM概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器。 由于Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(多于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,

  • Jinhanlai
69 min read
面试准备

Java 面试题

Java Java的三大特性:封装、继承、多态 封装:封装指的是隐藏具体属性和实现细节,仅对外提供公共访问方式。例如提供的setter和getter方法来访问私有属性。 继承:继承是指将多个相同的属性和方法提取出来,新建一个父类。Java中一个类只能继承一个父类,且只能继承访问权限非private的属性和方法。 子类可以重写父类中的方法,命名与父类中同名的属性。 可以进行代码复用。 多态:一个方法有多种实现结果,多态可以分为两种:设计时多态和运行时多态。 设计时多态:即重载,是指Java允许方法名相同而参数不同(返回值可以相同也可以不相同)。 运行时多态:即重写,是指Java运行根据调用该方法的类型决定调用哪个方法。 Java 基础 throw 和 throws

  • Jinhanlai
66 min read

A fast trajectory outlier detection approach via driving behavior modeling

DB-TOD 论文地址 摘要 轨迹数据捕获了道路网络上车辆(如汽车、出租车)的运动,并且轨迹异常值(或“异常轨迹”)表示与其他轨迹显著不同的轨迹。注意,对于轨迹异常检测问题,每个轨迹对应于给定的源和目标对(SD-pair),并且给定SD对的异常轨迹预计与对应于相同SD对的正常轨迹非常不同。以图1为例。它设计了两个SD对,分别表示为<S1、D1>和<S2、D2>,并绘制了从S1(S2)到D1(D2)的许多轨迹。

  • Jinhanlai
14 min read
JAVA源码

JAVA--集合类

java集合类 1. 简介 虚线箭头表示实现接口,实现箭头表示继承基类 1.1 总结 集合类可以分为三种:Map(映射)、Set(集合)、List(列表),其中set 和list 都实现了Collection接口;map 实现了Map接口。 集合和数组的区别? 集合长度可变;数组长度固定 集合只能存放引用类型;数组既可以存放引用类型,也可以存放基本类型。 集合可以存放不同类型的数据;数组只能存放同一类型的数据。 list 和 set 的区别? list插入的数据是有序的;

  • Jinhanlai
16 min read
spring

SpringMVC-原理

SpringMVC原理 1. 概述 1、客户端发送请求至前端控制器Dispatcherservlet 2、前端控制器根据请求调用处理器映射器(HandlerMapping)查找对应的处理器执行链(包含处理器和拦截器),并返回给前端控制器 3、前端控制器根据返回的控制器匹配器调用 处理器适配器(HandlerAdapter)执行器去执行对应的处理器. 4、控制器也就是具体的Controller执行对应的业务后返回modelandview,并由处理器接收并返回给前端控制器 5、前端控制器调用ViewResolver对modelandview进行解析定位试图资源 6、视图再讲数据模型进行渲染,然后返回view试图 6、将解析完成的view返回给客户端 自己只需要完成Controller 和View ,其他就是spring来完成 2. 代码示例 新建web项目; 导入springmvc的依赖

  • Jinhanlai
5 min read
Java

JAVA设计模式--代理模式

代理模式 代理模式是指客户端并不直接调用实际的对象,而是通过调用代理对象,来间接的调用实际的对象。 springboot 的aop(面向切面编程) 就是使用了代理的思想, 1. 静态代理 静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。 缺点: 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要重新维护. 2. Demo /** * @Author laijinhan * @date 2020/12/14 下午9:09 */ /** * 抽象产品接口 */ interface UserService

  • Jinhanlai
5 min read
SpringBoot

Spring--IoC容器

Spring--IoC容器 1. 简介 IoC概述 Spring Ioc指的是控制反转(IoC),IoC也被称为依赖注入(DI)。在此过程中,对象仅通过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依赖项(即,与它们一起使用的其他对象)。然后,容器在创建bean时注入那些依赖项。 在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。Bean是由Spring IoC容器实例化,组装和管理的对象。否则,bean仅仅是应用程序中许多对象之一。Bean及其之间的依赖关系反映在容器使用的配置元数据中。 IOC的解释参考文章 IOC 就是把对象的创建、赋值和管理交给容器来实现。只需要知道对象的名称即可,对象的创建和复制交给容器来解决,降低了系统的耦合度。可以通过XML配置

  • Jinhanlai
11 min read
数据结构

数据结构--排序算法

排序算法 1. 时间复杂度分析 不稳定的有:选择排序、希尔排序、快速排序、堆排序 In-place占用常数内存,不占用额外内存 Out-place: 占用额外内存 稳定性:如果a=b,a在b的前面,排序过后a还是在b的前面 图片引用 2. 冒泡排序 /** * 冒泡排序 * @param arrays 需要排序的数组 * @return 排序后的结果 * @description * 1. 比较相邻的元素。如果第一个比第二个大,就交换它们两个。 * 2. 每次比较过后,

  • Jinhanlai
9 min read
软件设计模式

JAVA设计模式--设计原则

JAVA设计模式-设计原则 六大设计原则包括:单一职责原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特法则、开闭原则 1. 单一职责原则 单一职责是指一个类只负责一个职责。比如现在比较流行的微服务,就是将之前很复杂耦合性很高的业务,分成多个独立的功能单一的简单接口,然后通过服务编排组装的方式实现不同的业务需求,而这种细粒度的独立接口就是符合单一职责原则的具体实践。 2. 开闭原则 开闭原则指的是对拓展开放、对修改关闭。它是说我们在实现一个新功能时,首先应该想到的是扩展原来的功能,而不是修改之前的功能。 3. 里氏替换原则 里氏替换原则是面向对象(OOP)编程的实现基础,它指的是所有引用了父类的地方都能被子类所替代,并且使用子类替代不会引发任何异常或者是错误的出现。 4. 依赖倒置原则 依赖倒置原则指的是要针对接口编程,

  • Jinhanlai
2 min read
软件设计模式

JAVA设计模式--适配器模式

JAVA设计模式-适配器模式 1. 简介 什么是适配器模式? 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作 适配器模式属于结构型模式 适配器实现了统一管理,一个目标是适配接口对象多个适配器类 优缺点? 优点: 增加了类的透明性和复用性,将具体的实现封装在适配者类中 对象适配器模式还可以将不通的适配者适配到同一个目标接口上 缺点: 过多的使用适配器类会让程序变得复杂 类适配器模式还存在单继承的问题 代码示例 /** * @Author laijinhan * @date 2020/9/13 10:49 上午 */ import lombok.AllArgsConstructor; /** * 被适配的类 */ class Adaptee{

  • Jinhanlai
1 min read
软件设计模式

JAVA设计模式--建造者模式

JAVA设计模式-建造者模式 1. 概述 简介 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 建造者模式是一步一步创建一个复杂的对象,建造者模式注重的是一步一步的创建复杂对象。这个和工厂模式存在区别。 优缺点 优点 将产品本身和其创建过程解耦,用户不需要知道内部组成的细节。 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则“ 具体的建造者完全独立,使用不同的具体建造者生产不同的对象 缺点 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式 如果产品内部变化很复杂,则需要大量的具体建造者,会导致系统更加庞大 代码示例: /** * @Author laijinhan * @date 2020/

  • Jinhanlai
2 min read
软件设计模式

JAVA--UML类图

类图 1. 泛化关系 也称之为继承关系,为is-a的关系;通常用来继承非抽象类,是依赖关系的一种特例。在UML类图中使用带实心三角箭头的实线表示,(如果A类和B类存在类继承关系,那么在UML类图中就可以使用泛化关系来描述。) 箭头指向:带三角箭头的实线,箭头指向父类 2. 依赖关系 带普通箭头的虚线表示。(依赖关系就是一个类A中使用到对方类B,例如私有变量使用B类,方法参数使用B类,构造方法等,那么就可以说是A类依赖B类。在UML类图中就可以使用依赖关系表示。) 是一种使用的关系,即一个类的实现需要另一个类的协助,所以要尽量不使用双向的互相依赖. 箭头指向: 带箭头的虚线,指向被使用者 3. 实现关系 是依赖关系的一种特例,在UML类图中使用带实心三角箭头的虚线表示.(如果A类实现了B接口,

  • Jinhanlai
3 min read
软件设计模式

JAVA设计模式--单例模式

单例模式 1. 简介 单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。 单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。单例模式又名单件模式或单态模式。 单例的构造函数为私有 提供一个自身的静态私有成员变量; 提供一个公有的静态工厂方法 2. 优缺点 优点: 由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。 提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它,并为设计及开发团队提供了共享的概念。 缺点: 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。

  • Jinhanlai
6 min read
R

R

R 语法教程 R语言中,变量本身没有声明任何数据类型,而是获取分配给它的R - 对象的数据类型。 所以R称为动态类型语言. R语言中数组、数据帧、矩阵默认都是按列来排放数据,只有矩阵可以设置byrow=TRUE来按行排放 R语言中下标是以1开始 基础语法 描述 语法 取余 %% 取商 %/% 管道,左边的结果当做输入传入右边 %>% 指数 ^ 两个向量第一个元素进行与操作 && 判断元素是否在向量里面 %in% 矩阵与其转置相乘 %* % 合并数据帧 merge()参考链接 拆分数据

  • Jinhanlai
2 min read
Python

Python排忧解难

python排忧解难 菜鸟教教程 list、array和Tuple的区别 list list是python内置函数,它的数据类不必相同的。在list中的数据类型保存的是数据的存放的地址,简单的说就是指针,并非数据.用append()函数来添加元素;del list[2]来删除下标为2的元素;用in来判断元素是否在列表里面; 注意直接复制list会出现浅拷贝问题,需要用copy()函数来解决 array numpy里面封装的array的中的类型必须全部相同, array的创建:参数既可以是list,也可以是元组.使用对应的属性shape直接得到形状 Tupple 元组和列表类似,但是元组中的元素不能修改 赋值、浅拷贝和深拷贝 参考地址 赋值

  • Jinhanlai
1 min read
软件设计模式

JAVA 设计模式--工厂模式

JAVA设计模式--工厂模式 1. 简介 工厂方法(Factory Method)模式是类的创建模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。(工厂方法又称为虚构造器)。 简单工厂模式属于创建型模式,属于工厂模式中的一种,简单工厂模式就是由一个工厂对象来决定创建出一种具体的产品 在简单工厂模式中,我们会定义一个创建对象的类,多使用反射的方法来创建具体产品实例,这个类用来封装实例化对象的行为。 在软件开发中,当我们需要大量的创某种,某类或者某一批对象时候,就可以考虑使用简单工厂模式 2. 模式的适用性 当一个类不知道它所必须创建的对象的类的时候。 当一个类希望由它的子类来指定它所创建的对象的时候。 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。 3. 为什么要使用工厂模式 为了解藕,把对象的创建和使用过程分开 减少重复的代码,

  • Jinhanlai
3 min read

8086微型计算机

1 微型计算机的硬件组成 微型计算机系统的硬件由运算器、控制器、存储器、输入设备和输出设备五大基本部件组成。 1.1 微处理器 微处理器包含运算器和控制器,微处理器的性能基本决定了计算机的性能 1.2 协处理器 协处理器用于特定任务的处理,以减轻系统微处理器的负担,是微型计算机系统的选配硬件。 1.3 内存储器(内存、主存) 内存储器用于存放计算机正在运行的程序和用到的数据等,分为随机存取存储器RAM和只读存储器ROM两大类。 RAM接受程序的控制,可由用户写入数据或读出数据,但是断电后数据会消失。RAM可以用来临时存放程序、输入数据和中间结果等。 ROM中的信息由厂家预先写入,一般用来存放自检程序、配置信息等。通常只能读出而不能写入,

  • Jinhanlai
12 min read
c/c++

c/c++笔记

面向对象 函数重载与运算符重载 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载 classname operator+(const classname&); +运算符重载的写法 多态 C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。 静态多态 也称为静态链接 - 函数调用在程序执行前就准备好了,有时候也称为早绑定。 虚函数 虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。 我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定 数据抽象 数据抽象是指,只向外界提供关键信息,

  • Jinhanlai
2 min read