spring家族
Spring 家族Spring常见问题总结
SpringIOC
IOCIOC原理IOC(Inversion of Control):控制反转 Spring Core最核心的部分 需要先了解依赖注入(Dependency Inversion) 依赖注入含义把底层类作为参数传递给上层类,实现上层对下层的“控制” 使用依赖注入的代码实例 需要修改轮胎时只用改一下轮胎就行了,不再需要大动干戈 IOC、DI、DL的关系DL(Dependency Lookup):依赖查找(已经被抛弃,需要用户自己使用API查找对象) 依赖注入的方式 Setter 实现特定属性的pulic setter来让IOC容器调用注入所依赖类型的对象 Interface 实现特定的接口以供IOC容器注入所依赖类型的对象 Constructor 基于构造函数,实现特定参数的构造函数,在创建对象时让IOC容器注入所依赖类型的对象 Annotation 基于注解,通过Java的注解机制来让IOC容器注入所依赖类型的对象 如Autowired 依赖倒置原则、IOC、DI、IOC容器的关系 依赖倒置原则是一种思想:高层模块不应该依赖低层模块,两者都应该依赖其抽...
SpringAOP
Spring AOP 关注点分离:不同的问题交给不同的部分去解决。 面向切面编程AOP正是此种技术的体现。 通用化功能代码的实现,对应的就是所谓的切面(Aspect)。 业务功能代码和切面代码分开后,架构将变得高内聚低耦合。 确保功能的完整性:切面最终需要被合并到业务中(Weave) AOP的三种织入方式 编译时织入:需要特殊的Java编译器,如AspectJ。 类加载时织入:需要特殊的Java编译器,如AspectJ和AspectWerkz。 运行时织入:Spring采用的方式,通过动态代理的方式,实现简单。 SpringBoot 切面实例 AOP主要名词概念 Aspect:通用功能的代码实现。 Target:被织入Aspect的对象。 Join Point:可以作为切入点的机会,几乎所有方法都能做为切入点。 Pointcut:Aspect实际被应用在的Join Point,支持正则 Advice:类里的方法以及这个方法如何织入到目标方法的方式 Weaving(织入):AOP的实现过程 Advice种类 前置通知:Before 后置通知:AfterRet...
Java异常体系
Java 异常体系异常处理机制主要回答了三个问题 What:异常类型回答了什么被抛出 Where:异常堆栈跟踪回答了在哪抛出 Why:异常信息回答了为什么被抛出 异常体系 Error和Exception的区别从概念角度解析java异常处理机制 Error:程序无法处理的系统错误,编译器不做检查 一般是与Jvm相关的问题,如系统崩快,内存不住,stackOverFlow等 仅靠程序本身无法恢复 Exception:程序可以处理的异常,捕获后可以恢复 总结:前者是程序无法处理的错误,后者是可以处理的错误。 Exception: RuntimeException:不可预知,程序应该自行避免 如访问空指针,数组下标越界,除0 非RuntimeException:可预知的,从编译器校验的异常 如文件不存在而打开文件失败 从责任的角度 Error属于JVM需要承担的责任 RuntimeException是程序应该负担的责任 Checked Exception可检查异常是Java编译器应该负担的责任 常见Error及Exception 异常处理机制 抛出异常:...
Map体系
Map体系 HashMap、HashTable、ConcurrentHashMapHashMap(Java 8以前):数组+链表 数组长度默认16 存储规则:hash(key.hashCode())%len HashMap(Java 8及以后):数组+链表+红黑树 通过常量TREEIFY_THRESHOLD决定是否将链表转化为红黑树 使用LazyLoad原则,首次使用时才会初始化数组 HashMap:如何有效减少碰撞 扰动函数:促使元素位置均匀分布,减少碰撞几率。 使用final对象,并采用合适的equals()和hashCode()方法。 Hash函数 高16位与低16位做异或,让结果更均匀,同时数组长度总是二的倍数,方便取下标,直接多取一位就行了。 HashMap:扩容问题 多线程条件下,调整大小会存在条件竞争,容易造成死锁 reHashing是一个比较耗时的过程(将原来的内容重新移到新的hash值对应的桶中) HashMap在JDK1.8之后引入了红黑树的概念,表示若桶中链表元素超过8时(并且数组的大小是64),会自动转化成红黑树;若桶中元素小...
Java的IO机制
JAVA的I/O机制BIO、NIO、AIOBIO:Block-IO 基于字节流和字符流进行操作 如InputStream和OutputStream,Reader和Writer 两端都会阻塞。 缺点:效率低 NIO:NonBlock-IO构建多路复用的、同步非阻塞的IO操作 第一个阶段:程序不断询问内核是否数据准备完成,非阻塞 第二个阶段:拷贝数据阻塞等待 NIO核心: Channels Buffers Selectors Channel类似流,数据可以从Channel读到Buffer,也可以从Buffer写入Chennel NIO-Channels FileChannel 其有两个方法: 避免了两次用户态和内核态间的上下文切换,即“零拷贝”,效率较高。 DatagramChannel SocketChannel ServerSocketChannel NIO-Buffers ByteBuffer CharBuffer DoubleBuffer FloatBuffer IntBuffer LongBuffer ShortBuffer MappedBy...
Buffer缓冲区的原理及应用
Buffer的原理及应用缓冲区的概念数据在缓冲区中排队,你先入先出的形式读写。先写入的数据先被读出来。所以看上去缓冲区像一个水管,数据流入缓冲区,然后再流出。 缓冲区内部是用于存储数据的数据结构。可能是数组、可能是链表、甚至可能是复杂的树结构,比如哈希表、树等等都有可能。 比如一个聊天服务,在处理用户发送的消息时,例如微信,一定不能马上处理这条消息。而是应该先缓冲。如果你马上处理这些消息,当并发量高的时候,总有你处理不过来的时候。而你对消息进行了缓冲有很多的好处,首先是避免了瓶颈的出现(运算性能的瓶颈。Io性能的瓶颈)。其次,有时候批量处理数据的成本更低。比如批量写入磁盘。批量发送网络请求。可以更好的利用底层的设施,比如批量写入磁盘数据就比单个一点点写入快很多很多,这些都是缓冲区的价值。 缓冲区操作 flip() 翻转:读写切换 clear() :清空缓冲区 rewind() :重读或重写 flip操作读取这样的缓冲区就需要进行缓冲区的翻转,也就是flip操作。 上图中的flip操作,将position设置为0,limit设置为position的位置。这样就从一个写入缓...
线程
线程Thread中的start和run方法的区别 调用start()方法会创建一个新的子线程并启动 run()方法只是Thread的一个普通方法的调用 Thread和Runnable的关系Runnable是一个接口,Thread是一个类实现了Runnable接口。 因类的单一继承原则,推荐多使用Runnable接口 如何给run()方法传参 构造函数传参 成员变量传参 回调函数传参 如何实现处理线程的返回值 主线程等待法 主线程循环等待,直到子线程返回 缺点:代码臃肿,不知道等待多久,容易出问题 使用Thread类的join()阻塞当前线程以等待子线程处理完毕 缺点:粒度不够细 通过Callable接口实现:通过FutureTask或者线程池获取 public class MyCallable implements Callable { @Override public String call() throws Exception { String value=”test”; ...
多线程
多线程与并发线程安全问题的主要诱因 存在共享数据(临界资源) 存在多条线程共同操作这些共享数据 解决问题的根本办法:同一时刻有且只有一个线程再操作共享数据,发其他线程必须等到该线程处理完数据后再对共享数据进行操作。 互斥锁的特性 互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程的协调机制,这样在同一时间只有一个线程对需要同步的代码块进行访问。互斥性也称为操作的原子性。 可见性:必须确保在锁被释放之前,对共享变量所作的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作,从而引起不一致。 synchronizedsynchronized锁的不是代码,是对象 根据获取的锁的分类: 获取对象锁 主要有两种用法: 同步代码块(synchronized(this) , synchronized(类实例对象)),锁是小括号()中的实例对象。 同步非静态方法(synchronized method),锁是当前对象的实例对象。 获取类锁 两种方法: 同步代码块(synchroni...
jmm的内存可见性
jmm的内存可见性Java内存模型jmmJava内存模型(即Java Memory Model,简称JMM)本身是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。 JMM中的主内存 存储java实例对象 包括成员变量、类信息、常量、静态变量等 属于数据共享的区域,多线程并发操作时会引发线程安全问题 JMM中的工作内存 存储当前方法的所有本地变量信息,本地变量对其他线程不可见 变量会从主内存拷贝到工作内存,每个线程只能访问自己的工作内存 其内还包括字节码行号指示器,Native方法信息。 属于线程私有数据区域,不存在线程安全问题 JMM与Java内存区域JMM与Java内存区域划分是不同的概念层次 JMM描述的是一组规则,围绕原子性,有序性,可见性展开,控制程序中各个变量在共享数据区域和私有数据区域的访问方式 相似点:存在共享区域和私有区域 JMM中主内存是共享区域(在Java内存区域中应该包括堆和方法区),工作内存是私有区域(在Java内存区域中应该包括程序计数器...








