Zookeeper基础入门
Zookeeper是一个分布式的、开源的分布式应用程序的协调服务,基于ZAB协议(ZooKeeper Atomic Broadcast)实现分布式数据一致性
Zookeeper内部的数据模型类似文件系统的树形结构(ZNode),每个节点可存储不超过1MB的数据
Zookeeper提供的主要功能包括:
服务注册与发现
配置管理
分布式锁
集群管理
Zookeeper数据模型ZooKeeper是一个树形目录服务,其数据模型和Unix的文件系统目录树很类似,拥有一个层次化结构
这里面的每一个节点都被称为ZNode,每个节点上都会保存自己的数据和节点信息
节点可以拥有子节点,同时也允许少量(1MB)数据存储在该节点之下(可以通过jute.maxbuffer修改单个节点数据大小限制)
节点可以分为四大类:
PERSISTENT:持久化节点,创建后永久存在(除非显式删除)
EPHEMERAL:临时节点 -e,会话结束后自动删除(用于实现服务注册与心跳检测)
PERSISTENT_SEQUENTIAL:持久化顺序节点 -s,顺序节点的名称后面会自动追加单调递增序号(如 /lock/seq-00 ...
dubbo基础入门
Dubbo是一款高性能RPC(Remote Procedure Call,远程过程调用)框架,专注于分布式服务治理,提供服务发现、负载均衡、容错等能力
Dubbo架构Dubbo的架构包含5个核心角色:
Provider:服务提供者,暴露服务接口
Consumer:服务消费者,调用远程服务
Registry(注册中心):服务注册和发现的注册中心,存储服务元数据(如 IP、端口),支持 ZooKeeper/Nacos/Redis等注册中心
Monitor(监控中心):统计服务调用次数和耗时
Config Center(配置中心):动态调整参数(如超时时间)
Dubbo快速入门采用SpringBoot+Dubbo+Zookeeper实现服务提供者和消费者之间的调用:
dubbo-provider: 服务提供者
dubbo-consumer: 服务消费者
由于提供者和消费者之间需要统一类,所以两者通常要依赖同一个公共接口,编写一个接口类:
package com.example.api;public interface GreetingService { ...
JUC线程池
利用多线程,程序可以更加合理地使用CPU多核心资源,在同一时间完成更多的工作。但是,如果程序频繁地创建线程,由于线程的创建和销毁也需要占用系统资源,因此这样会降低整个程序的性能,利用线程池可以将已创建的线程复用,利用池化技术,就像数据库连接池一样,创建很多个线程,然后反复地使用这些线程,而不对它们进行销毁。
由于线程池可以反复利用已有线程执行多线程操作,所以它一般是有容量限制的,当所有的线程都处于工作状态时,那么新的多线程请求会被阻塞,直到有一个线程空闲出来为止,这里会用到阻塞队列
使用方式线程池的构造方法:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ...
JUC并发容器与并发工具
并发容器在单线程模式下,集合类提供的容器可以说是非常方便了,比如链表、顺序表、哈希表等数据结构,但是这些容器在多线程环境下,并不能正常工作。要解决并发情况下的容器问题,可以给方法前面加个synchronzed,或者使用Vector或是Hashtable,但是它们的效率实在是太低了,完全依靠锁来解决问题。
JUC提供了专用于并发场景下的容器,比如可以代替ArrayList的CopyOnWriteArrayList:
public static void main(String[] args) throws InterruptedException { List<String> list = new CopyOnWriteArrayList<>(); //使用CopyOnWriteArrayList保证线程安全 Runnable r = () -> { for (int i = 0; i < 100; i++) list.add("aaa"); }; ...
JUC锁类和原子类
锁类在JDK 5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,Lock接口提供了与synchronized关键字类似的同步功能,但需要在使用时手动获取锁和释放锁。
Lock和Condition接口使用并发包中的锁和synchronized锁不太一样,这里的锁可以认为是一把真正意义上的锁,每个锁都是一个对应的锁对象,只需要向锁对象获取锁或是释放锁即可。Lock接口定义:
public interface Lock { //获取锁,拿不到锁会阻塞,等待其他线程释放锁,获取到锁后返回 void lock(); //同上,但是等待过程中会响应中断 void lockInterruptibly() throws InterruptedException; //尝试获取锁,但是不会阻塞,如果能获取到会返回true,不能返回false boolean tryLock(); //尝试获取锁,但是可以限定超时时间,如果超出时间还没拿到锁返回false,否则返回true,可以响应中断 boolean tryLock(long time, ...
JVM类与类加载
java的类字节码文件如何加载到内存中的?
类加载过程类加载的触发条件JVM并不会一次性加载所有类,而是采用“按需加载”策略,即在需要的时候才会进行类的加载。
触发类加载的操作一般在这些情况下,如果类没有被加载,那么会被自动加载:
使用 new 关键字创建对象时
MyClass obj = new MyClass();
访问类的静态变量(包括读取或写入,不是 final 修饰的常量)时
int value = MyClass.staticField;
调用类的静态方法时
MyClass.staticMethod();
使用反射机制(如 Class.forName()、Class.getMethod() 等)时
Class<?> clazz = Class.forName("com.example.MyClass");
子类初始化时,如果父类尚未初始化,会先触发父类的加载
class A { static int a = 10; }class B extends A { static int b = ...
JVM垃圾回收机制
Java会自动管理和释放内存,它不像C/C++那样要求我们手动管理内存,JVM提供了一套全自动的内存管理机制,当一个Java对象不再用到时,JVM会自动将其进行回收并释放内存,那么对象所占内存在什么时候被回收,如何判定对象可以被回收,以及如何去进行回收工作也是JVM需要关注的问题。
对象存活判定算法对象在什么情况下可以被判定为不再使用已经可以回收了?
引用计数法如果要经常操作一个对象,那么首先一定会创建一个引用变量:
//str就是一个引用类型的变量,它持有对后面字符串对象的引用,可以代表后面这个字符串对象本身String str = "abc";
只要一个对象还有使用价值,就可以通过它的引用变量来进行操作,那么可否这样判断一个对象是否还需要被使用:
每个对象都包含一个引用计数器,用于存放引用计数(存放被引用的次数)
每当有一个地方引用此对象时,引用计数+1
当引用失效(比如离开了局部变量的作用域或是引用被设定为null)时,引用计数-1
当引用计数为0时,表示此对象不可能再被使用,因为这时我们已经没有任何方法可以得到此对象的引用了
但是这样存在一个 ...
JVM概述与内存管理
JVM启动流程虚拟机的启动入口位于jdk/src/share/bin/java.c的JLI_Launch函数,整个流程分为如下几个步骤:
配置JVM装载环境
解析虚拟机参数
设置线程栈大小
执行JavaMain方法
JLI_Launch函数的定义,在入口点的参数有很多个,其中包括当前的完整版本名称、简短版本名称、运行参数、程序名称、启动器名称等:
intJLI_Launch(int argc, char ** argv, /* main argc, argc */ int jargc, const char** jargv, /* java args */ int appclassc, const char** appclassv, /* app classpath */ const char* fullversion, /* full version defined */ const char* dotversion, ...
设计模式——行为型模式
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。
行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。
行为型模式分为:
模板方法模式
策略模式
命令模式
职责链模式
状态模式
观察者模式
中介者模式
迭代器模式
访问者模式
备忘录模式
解释器模式
以上11种行为型模式,除了模板方法模式和解释器模式是类行为型模式,其他的全部属于对象行为型模式
解释器模式解释器顾名思义,就是对语言进行解释,根据不同的语义来做不同的事情。笼统点来讲就是给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
在解释器模式中,我们需要将待解决的问题,提取出规则,抽象为一种“语言”。比如加减法运算,规则为:由数值和+-符号组成的合法序列,“1+3-2” 就是这种语言的句子。
比如计算器就是根据输入的算式,去进 ...
设计模式——结构型模式
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。
由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。
结构型模式分为以下7种:
代理模式
适配器模式
装饰者模式
桥接模式
外观模式
组合模式
享元模式
代理模式由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生成,而动态代理代理类则是在Java运行时动态生成。动态代理又有JDK代理和CGLib代理两种。
静态代理火车站买票案例,如果要买火车票的话,需要去火车站买票,坐车到火车站,排队等一系列的操作,显然比较麻烦。而火车站在多个地方都有代售点,我们去代售点买票就方便很多了。火车站是目标对象,代售点是代理对象。
//卖票接口public interface SellTickets ...