# JavaCode **Repository Path**: fzy2016/java-code ## Basic Information - **Project Name**: JavaCode - **Description**: 学习Java过程中所敲的代码以及总结的笔记 - **Primary Language**: Java - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 30 - **Created**: 2022-04-21 - **Last Updated**: 2022-04-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [toc] # JavaCode 学习java过程中所敲的代码和笔记 ## JavaSE 1. 通过Java的历史和演变对Java的应用范围有一定的了解,主体功能; 2. 熟悉JDK、JRE、JVM的概念和区别; 3. Java语言的注释、关键字、标识符的定义规则(不能数字开头、不能是关键字)、数据类型(基本:byte1 short2 int4 long8 floa4t double8 boolean1 char2,引用:类String 数组 接口); 4. ASCII编码表也要了解:(0-48,9-57,A-65,Z-90,a-97,z-122);486597 5. 常用DOS命令:(cls,ipconfig,cd \,dir,d:+回车); 6. Java运算符:&& || !,三目运算符; 7. Java数组(数组中的元素可以是`任何`数据类型),以及基本数据类型(char \u0000)和引用数据类型的默认值,二维数据的在堆栈的内存分布情况,数组的工具类Arrays的常用方法:equals,fill,sort,toString; 8. 熟悉switch(byte|short|int|String|enum){case xx: yyy break },for循环(特别是两层嵌套)、while(条件){循环体;步长;},以及break和continue的用法和场景; 9. 为什么数组获取长度用length,字符串获取长度用length(); 10. Object类中常用的方法:getClass(),hashCode(),equals(),clone(),toString(),finalize()垃圾回收前执行,wait(),notify(),notifyAll()线程相关; 1. JVM会使用对象的hashcode值来提高对HashMap、Hashtable哈希表存取对象的使用效率。 2. ==判断的是内存地址; 12. Object类的toString()方法默认返回该对象实现类的“类名+@+hashcode”值(十六进制hashcode); 13. 常用API也要牢记: 14. sc.nextInt(),sc.next()遇到空格结束,sc.nextLine(); 15. `random.nextInt(10) + 20;`[20,30),不给值默认再int范围内随机生产; 3. 字符串常量池:程序中直接写上上引号的字符串,就存储在字符串常量池中。 1. 基本数据类型:== 比较的数值,引用数据类型:== 比较的是内存地址。 2. String 专门给我们提供了一个方法用于字符串的比较:使用equals方法来完成字符串的比较。字符串使用equals比较的时候,比较是字符串里面的每一个字符。 3. substring(int begin, int end); (从零开始)字符串截取, 包前不包后[ begin , end ) 4. `Arrays.sort(strArray, Collections.reverseOrder())`降序排序(Arrays.sort()默认是升序); 8. Math.abs()绝对值,Math.ceil()向上取整,Math.floor()向下取整,Math.round()四舍五入; 9. 泛型必须是引用数据类型 10. ArrayList.add(e),ArrayList.add(idx,e),remove(idx),get(idx),set(idx,e),size() 11. new Date(0)计算机元年1970,date.getTime()获取时间零点到当前时间的毫秒值 12. new SimpleDateFormat(格式yyyy MM dd HH mm ss);sdf.format(Date),sdf.parse(String); 13. Calendar.getInstance()获取Calendar实例 14. System.currentTimeMillis(),`System.arraycopy(Object src,srcPos,Object dest,destPos,length)` 16. 静态代码块 > 非静态代码块 > 构造器,静态代码块只执行一次,非静态代码块,每次进入到当前类的时候都会执行一次。 17. final修饰的引用数据类型,不能改变引用的地址能改变其属性值。 18. 使用了final关键字修饰一个类那么这个使用final修饰的类不能有任何的子类但是可以拥有父类 19. 重载:方法名相同,参数列表不同,方法返回值可以不同,权限修饰符可以不同。 20. 子类方法的访问权限可以大于等于父类,返回值要小于等于父类; 21. 只要创建子类的对象:父类的构造函数一定会被调用。如果父类中的构造方法被重写,一定要在父类中添加无参的构造方法,否则会报错(因为子类会调用); 22. 在抽象的类中,可以重写也可以不重写接口中的抽象方法; 23. 接口jdk8新增默认方法,解决接口升级所来的大量影响,jdk9增加了私有方法解决抽取公共代码,减少代码冗余,提高了代码的复用性。 24. 多态:父类引用指向子类对象,前提是extends implements,属性编译和运行期-父类;行为:前期绑定-编译时绑定的时父类,后期绑定-运行时绑定的是子类;instanceof 25. 方法里面的局部内部类不能使用权限修饰符,protected修饰的方法在不同包里面,只有子类对象可以调用。 26. Optional,Optional.of(T),Optional.ofNullable(T); 27. @Befer,@Test,@After 28. 反射:Class.forName("全类名"),类名.class,对象名.getClass()三种获取的Class对象都是同一个; 29. Class对象.getName()获取全类名,Class对象.getClassLoader()返回类加载器,Class对象.getInterfaces()获取实现的接口,Class对象.`getPackage()` 获取此类的包,也可以通过Class对象获取成员变量们,成员方法们,构造方法们; 30. 相同情况下使用StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。单线程操作字符串缓冲区下操作大量数据,使用StringBuilder; 31. Lambda表达式格式:`(参数类型 参数名称) ‐> { 代码语句 }` 1. `对象:: 实例方法名` 2. `类:: 静态方法名` 3. `类:: 实例方法名` 32. `枚举类的对象,多个对象之间用","隔开,末尾对象";"结束`,Enum类.values()获取枚举类型的对象数组,Enum类.valueOf(String str)把一个字符串转为对应的枚举类对象; ## JavaSE-集合 1. Map接口{HashMap-->LinkedHashMap`、`TreeMap`和`Properties},Collection接口{List接口(**元素有序、元素可重复**:ArrayList,LinkedList,Vector),Set接口(**元素无序,而且不可重复**:HashSet-->LinkedHashSet,TreeSet)} 2. Collection常用方法:add(E),clear(),remove(E),contains(E),isEmpty(),size(),toArray(); 3. Collection`接口与`Map`接口主要用于存储元素,而` Iterator `主要用于迭代访问(即遍历)`,Collection.iterator()获取迭代器,常用方法:it.hasNext(),it.next(); 4. `泛型的好处:将运行时期的ClassCastException,转移到了编译时期变成了编译失败。`泛型的上限: ``,泛型的下限: ``; 5. List接口常用方法:add(idx,e),get(idx),remove(idx),set(idx,e) 1. ArrayList集合元素增删慢,查找快;JDK1.7ArrayList`饿汉式,`直接创建一个初始容量为10的数组;`JDK1.8ArrayList像懒汉式,`一开始创建一个长度为0的数组,当添加第一个元素时再创建一个始容量为10的数组。 2. LinkedList(双向链表有prev和next变量)集合查询慢、但是方便元素添加、删除的集合。LinkedList常用方法:addFirst(e),addLast(e),getFirst(),getLast(),removeFirst(),removeLast(),pop()弹出一个元素,push(e),offer(e), isEmpty(),peek()获取第一个元素,但是不移除; 3. 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。对于新增和删除操作add(特指插入)和remove,LinkedList比较占优势,因为ArrayList要移动数据。 4. Vector和ArrayList几乎是完全相同的,唯一的区别在于Vector是同步类(synchronized),属于强同步类,Vector每次扩容请求其大小的2倍空间,而ArrayList是1.5倍。常用方法:addElement(o),insertElementAt(o,idx),removeElement(o); 6. 可变参数:方法名(int... arr),只能放在参数列表的最后面,其实编译成的class文件将这些元素先封装到一个数组中。 7. Collections 是集合工具类,常用方法:addAll(collection),shuffle(list)打乱,sort(list),sort(list,comparator比较器); 8. ArrayList根据age对Person进行排序: 1. Person 实现 Comparable接口,重写compareTo方法,使用Collections.sort(list)进行排序; 2. Collections.sort(list,new Comparator(){重写compare方法}); 9. HashSet存储的`元素是不可重复`的,`集合元素可以为null`,`线程不安全`(底层HashMap); 10. `当一个类有自己特有的“逻辑相等”概念,`当改写equals()的时候,总是要改写hashCode(),根据一个类的equals方法(改写后),两个截然不同的实例有可能在逻辑上是相等的,但是,根据Object.hashCode()方法,它们仅仅是两个对象。所以复写equals方法的时候一般都需要同时复写hashCode方法。 11. TreeSet(底层使用红黑树结构存储数据)要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。 12. Map接口中的常用方法:put(k,v),putAll(map),remove(k),clear(),get(k),containsKey(k),containsValue(v),size(),isEmpty() 13. Map的三种遍历方式: - map.keySet()-->keys(Set)-->map.get(key) - map.values()-->Collection(value)-->iterator()-->iter.hasNext(),iter.next() - map.entrySet() -->set-->Map.Entry-->getKey(),getValue() 14. HashMap-->JDK1.7Entry数组-->JDK18Node(hash+key+value+next)数组 15. TreeMap的key有自然排序Comparable和定制排序Comparator 16. 与HashMap不同,Hashtable是线程安全的,不允许使用 null 作为 key 和 value 17. HashTable的子类new Properties()的常用方法:==pros.load(InputStream/Reader)==,pros.setProperty(k,v),pros.getProperty(k), `System.getProperties` 方法就是返回一个 `Properties` 对象。 1. `stringPropertyNames()`:所有键的名称的集合。 18. Stream API 提供了一种高效且易于使用的处理数据的方式(类sql),集合讲的是数据,Stream讲的是计算。Stream的操作三个步骤:创建Stream-->中间操作-->终止操作; 1. 创建Stream:Collection.stream(),Collection.parallelStream(),Arrays.stream(数组),Stream.of(T... values),Stream.iterate(),Stream.generate() 2. 中间操作: 1. 筛选与切片:filter(lambda),distinct(n),limit(),skip(n) 2. 映射:map(f),flatMap(f) 3. 排序:sorted(自然排序),sorted(Comparator com定制排序) 3. 终止操作: 1. 匹配与查找:allMatch(f),anyMatch(f),noneMatch(f),findFirst(),findAny(任意一个),count(),max(Comparator),min(c),forEach(c) 2. 归约:stream().reduce(0, Integer::sum) 3. 收集:stream().collect(Collectors.toList()) ## JavaSE-IO流 1. `java.io.File` 类是**文件**和**目录路径名**的抽象表示,开发路径使用/,File类构造器有:File(path/parent,child/File parent,String child) 2. File类常用方法有:getAbsolutePath(),getPath(),getName(),length(字节),exists(文件/文件夹是否存在),isDirectory(),isFile(),createNewFile(不存在才创建),delete(),mkdir(),mkdirs(),list(返回文件/文件夹的名字),listFiles(返回的是File[]) - listFiles(FileFilter接口,重写accept(File)方法) 3. | 顶级父类们 | 输入流 | 输出流 | | ---------- | -------------------------- | --------------------------- | | **字节流** | 字节输入流 **InputStream** | 字节输出流 **OutputStream** | | **字符流** | 字符输入流 **Reader** | 字符输出流 **Writer** | 4. 下面我们分别从输入流和输出流来学习IO流: 5. 输出字节流:OutputStream抽象类,常用方法:close(),flush(),write(byte[] b),write(byte[] b,int off从0开始,int len),write(int) 1. FileOutputStream类,文件输出流,用于将数据写出到文件,构造方法FileOutputStream(File),FileOutputStream(str),FileOutputStream(File,true(append)),FileOutputStream(str,true(append)),回车符\r换行符\n 6. 输入字节流:InputStream抽象类,close(),read()从输入流读取数据的下一个字节,read(byte[]) 1. FileInputStream类是文件输入流,从文件中读取字节。构造方法FileInputStream(File),FileInputStream(str),fis.read()的返回值是: 2. 节流读取文本文件时,遇到中文字符时,可能不会显示完整的字符,因为一个中文字符可能占用多个字节存储。 7. 输出字符流:Writer抽象类,常用方法:close(),flush(),write(int),write(char[]),write(char[] b,int off,int len),write(str) 1. FileWriter类构造时使用系统默认的字符编码和默认字节缓冲区。FileWriter(File),FileWriter(str), 1. `flush` :刷新缓冲区,流对象可以继续使用。 2. `close`:关闭流,释放系统资源。关闭前会刷新缓冲区。 8. 输入字符流:Reader抽象类,close(),read(),read(char[]) 1. FileReader构造函数FileReader(File),FileReader(str) 9. IO异常处理有两种方式,一种是throw Exception,一种是try...catch...finally 1. JDK1.7优化后的try-with-resource语句,try(声明资源)会自动关闭 2. JDK1.9try-with-resource语句的try(对象)中可以放置对象; 10. IO流还有缓冲流、转换流、序列化流: 11. 缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,等凑够了缓冲区大小的时候一次性写入磁盘,减少系统IO次数,从而提高读写的效率。 12. BufferedInputStream(InputStream),BufferedOutputStream(OutputStream),BufferedReader(Reader),BufferedWriter(Writer),其中bufferedReader.readLine()有特有方法读取一行文字,bufferedReader.newLine()写出行分隔符(换行),试试使用缓冲流赋值一个大文件; 13. 字符集了解一下:ASCII字符集,GBK字符集(GBK编码),Unicode字符集(utf-8编码,utf-16编码,utf-32编码) 14. 转换流只是字符流来说的因为字节流不会出现乱码问题:InputStreamReader(InputStream),InputStreamReader(InputStream,"GBK"),OutputStreamWriter(OutputStream),OutputStreamWriter(OutputStream,"utf8"),读取GBK编码的文件通过转换流输出未utf8编码的文件。 15. 使用序列化流的对象需要满足两个条件:首先必须实现 `java.io.Serializable` 接口,类的属性不能被`transient` 关键字修饰(serialVersionUID序列化的版本号 表示序列化版本标识符的变量),序列化流ObjectOutputStream(OutputStream),常用方法writeObject(Object)将指定的对象写出。 16. 反序列化流ObjectInputStream(InputStream),readObject()返回Object,如果能找到一个对象的class文件,我们可以使用readObject()进行反序列化操作。 17. 打印流PrintStream,其实我们常用的`PrintStream out = System.out`,打印流中有我们常用的print(),println()方法,PrintStream(String filename)输出到filename中,使用System.setOut(out)可以改变System.out.println()的输出流向; 18. 内存操作流: 1. 字节内存流:`ByteArrayInputStream、ByteArrayOutputStream` 2. 字符内存流:`CharArrayReader、CharArrayWriter` 3. 内存操作流与基础流的区别: - `输出(ByteArrayInputStream):程序 → ByteArrayInputStream→ 内存;` - `输入(ByteArrayOutputStream):程序 ← ByteArrayOutputStream← 内存;` 19. ~~~~java // IO流部分必会写的内容 char[] chars = new char[1024]; int len; while ((len = fis.read(chars))!= -1){ fos.write(chars,0,len); } ~~~~ 20. Java NIO和IO的主要区别: 1. IO面向流,NIO面向缓冲区 2. IO是阻塞IO,NIO是非阻塞IO,NIO使用选择器Selectors 21. Java NIO系统的核心在于: 1. 通道(Channel)—传输 2. 缓冲区(Buffer)—存储。 22. 缓冲区: 1. `Buffer(IntBuffer,ByteBUffer) 主要用于与NIO 通道进行交互`,数据是从通道读入缓冲区,从缓冲区写入通道中的。 2. `标记、位置、限制、容量遵守以下不变式: 0 <= mark <= position <= limit后数据不能进行读写 <= capacity` 3. ByteBuffer.allocate(capacity)--> ByteBuffer,常用方法:buff.put(byte[]),buff.flip()切换读取数据模式,buff.get(byte[]),buff.clear()清空缓冲区(被遗忘状态),buff.mark()标记,buff.reset()恢复mark位置,buff.hasRemaining()判断缓冲区中是否还有剩余数据 4. ByteBuffer.allocate(n)非直接缓冲区——将缓冲区建立在 JVM 的内存中。 5. ByteBuffer.allocateDirect()直接缓冲区——将缓冲区建立在物理内存中。可以提高效率。 23. 通道Channel: 1. Channel `表示IO 源与目标打开的连接`。Channel接口--(FileChannel,DatagramChannel,SocketChannel,ServerSocketChannel)在 JDK 1.7 中的 NIO.2 增加XXXChannel.open()创建Channel,通过(RandomAccessFile、Socket、ServerSocket、DatagramSocket)FileInputStream.getChannel()也可以获取通道。 2. channel.write(buff)将缓冲区的数据写到通道,channel.read(buff)将通道中的数据读到缓冲区。 3. 理解通道分散读取与聚集写入的概念。通过write(ByteBuffer[]),read(ByteBuffer[])实现。 24. `传统的IO 流都是阻塞式的。`也就是说,当一个线程调用read() 或write()时,该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务。服务器端需要处理大量客户端时,性能急剧下降。 25. `Java NIO 是非阻塞模式的。`当线程从某通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。线程通常将非阻塞IO 的空闲时间用于在其他通道上执行IO 操作,所以单独的线程可以管理多个输入和输出通道。 channel.configureBlocking(false);开启非阻塞模式 26. 选择器(Selector)是SelectableChannle 对象的多路复用器,Selector 可以同时监控多个SelectableChannel 的IO 状况,也就是说,利用Selector可使一个单独的线程管理多个Channel。Selector 是非阻塞IO 的核心。SelectableChannle -->-->SocketChannel,ServerSocketChannel,DatagramChannel 27. Selector.open() 方法创建一个Selector。向选择器注册通道:`SelectableChannel.register(Selector sel,int ops);`当调用register(Selector sel, int ops) 将通道注册选择器时,选择器对通道的监听事件,需要通过第二个参数ops 指定SelectionKey.OP_READ...。 28. Java NIO 管道是2个线程之间的单向数据连接。 Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。 29. NIO2-->new Paths.get()-->new Path(),Files工具类,JDK7新特性:自动资源管理(Automatic Resource Management, ARM),该特性以try 语句的扩展版为基础。 ## JavaSE-多线程 1. 并发和并行的概念,当系统只有一个CPU时,线程会以某种顺序执行多个线程,我们把这种情况称之为线程调度。 2. 进程和线程的概念,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程,是系统运行程序的基本单位,一个进程可以同时并发的运行多个线程 3. 继承Thread重写run(线程执行体)方法,每一个执行线程都有一片自己所属的栈内存空间(联系JVM的虚拟机栈)Thread(),Thread(name),Thread(Runable,[name]),Thread(target)常用方法:getName()获取现场名称,start()--虚拟机调用该现场的run()方法,sleep(),currentThread()返回当前线程对象。 4. 创建线程的三种方式:extends Thread(),实现Runable接口重写run()——适合多个相同的程序代码的线程去共享同一个资源,Thread(new FutureTask(Callable的子类——重写call()方法)) 5. Java线程分为:守护线程,用户线程,Java垃圾回收就是一个典型的守护线程。 6. 若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。 7. Java线程同步机制: 1. 同步代码块synchronized(锁对象){} 1. 锁对象可以是任意类型。 2. 多个线程对象要使用同一把锁。 2. 同步方法 1. `对于非static方法,同步锁就是this。` 2. `对于static方法,我们使用当前方法所在类的字节码对象(类名.class)。` 3. 锁机制。 8. java.util.concurrent.locks.Lock 机制提供了比synchronized更广泛的锁定操作,同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象。lock()加同步锁,unlock()释放同步锁。 9. 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁,产生死锁的四个必要条件: 1. 互斥条件 2. 请求与保持条件 3. 不可剥夺条件 4. 循环等待条件 10. ![](https://img-blog.csdnimg.cn/20200303194713985.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l6cGJyaWdodA==,size_16,color_FFFFFF,t_70) 11. 线程创建之后它将处于 NEW(新建) 状态,调用 start() 方法后开始运行,线程这时候处于 READY(可运行)状态。可运行状态的线程获得了 cpu 时间片后就处于 RUNNING(运行) 状态。 12. 线程间通信——等待唤醒机制:线程A生产包子,线程B吃包子。**wait**方法与**notify**方法必须要由同一个锁对象调用,notifyAll()释放所通知对象的 wait set 上的全部线程。 13. 线程池的好处:减低资源消耗,提高响应速度,提高线程的可管理性。 14. 线程池接口是 `java.util.concurrent.ExecutorService` 。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在`java.util.concurrent.Executors` 线程工厂类里面提供了一些静态工厂,生成一些常用的线程池。`官方建议使用Executors工程类来创建线程池对象。` Executors类中有个创建线程池的方法如下: - `Executors.newCachedThreadPool():`创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 - `Executors.newFixedThreadPool(n); 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。` - `Executors.newSingleThreadExecutor()` :创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。 - `Executors.newScheduledThreadPool(n)`:创建一个定长线程池,支持定时及周期性任务执行。 阿里规约里面为什么线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险说明:Executors各个方法的弊端: 1. newFixedThreadPool和newSingleThreadExecutor:主要问题是推积的请求处理队列可能会耗费非常大的内存,甚至OOM) 2. newCachedThreadPool和newScheduledThreadPool:主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。 3. ```java public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); } ``` 线程池有哪些参数,各代表什么意思?线程池中提供哪些队列种类和拒绝策略呢? `corePollSize:`核心线程数。在创建了线程池后,线程中没有任何线程,等到有任务到来时才创建线程去执行任务。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。 `maximumPoolSize`:最大线程数。表明线程中最多能够创建的线程数量。 `keepAliveTime`:空闲的线程保留的时间。 `TimeUnit`:keepAliveTime参数的时间单位 `BlockingQueue`:阻塞队列,存储等待执行的任务。参数有ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue可选。 `ThreadFactory`:线程工厂,用来创建线程 `RejectedExecutionHandler`:队列已满,而且任务量大于最大线程的异常处理策略。 怎么使用线程池呢?ExecutorService.submit(new Runable(){重写run方法})从线程池中获取线程对象,然后调用MyRunnable中的run() ExecutorService.shutdown()关闭线程池。 ## MySQL数据库 1. DDL数据定义语言--建库建表,DML数据操纵语言,DQL数据查询语言,DML数据控制语言。 2. where 语句在分组之前过滤数据,即先过滤再分组(分组后聚合)所以 where 后面不可以使用聚合函数而 having 子句在分组之后过滤数据,即先分组再过滤,所以having 后面可以使用聚合函数。limit offset(从0开始),length。MySQL字符串截取:right(str,length),left(str,length),substring()。 3. MYSQL主键primary key约束:非空且唯一,唯一约束unique,非空约束not null default "dd",外键约束foreign key 4. 为什么要有事务?保证数据的一致性。事务开启之后, 所有的操作都会临时保存到事务日志中, 事务日志只有在得到 commit 命令才会同步到数据表中,其他任何情况都会清空事务日志(rollback,断开连接) 1. 事务的四大特性:ACID--原子性,一致性,隔离性,持久性 2. 事务并发访问的三个问题: 1. 脏读:一个事务读取到了另一个事务中尚未提交的数据 2. 不可重复读:一个事务中两次读取的数据内容不一致 3. 幻读:一个事务中两次读取的数据的数量不一致,这是 insert 或 delete 时引发的问题。 3. 事务隔离级别:一个事务与其他事务隔离的程度,隔离级别越高,性能越差,安全性越高。 1. 读未提交: 2. 读已提交:可以避免脏读(Oracle Sqlserver) 3. 可重复读:可避免脏读和不可重复读(Mysql) 4. 串行化:可以避免脏读、不可重复读和幻读 5. 数据表数据: 1. 1NF表中每列不可再拆分, 2. 2NF:在1NF的基础上,消除部分依赖,一张表只描述一件事情。 1. A(学号,课程名称)—> 姓名 姓名部分依赖于 3. 3NF:不产生传递依赖,表中每一列都直接依赖于主键。而不是通过其它列间接依赖于主键。 1. 学号—>系名 系名—>系主任 ,系主任传递依赖于学号 6. 索引:帮助数据库高效获取数据的数据结构,有序以某种方式引用指向数据。缺点:索引文件也不小,往往存在磁盘中,插入、更新、删除数据也需要维护索引。 7. Mysql存储引擎: 1. InnoDB引擎:支持BTREE(B树,B+树的结构)索引--数据有序范围查询,Full-text全文索引 2. MyISAM引擎:BTREE,Full-text,R-tree索引 3. InnoDB:行锁,支持事务,插入慢,内存和空间使用高 4. MyISAM:表锁,不支持事务,插入速度快,内存和空间使用低 5. 表锁:偏向MYISAM存储引擎,开销小,加锁快,不会出现死锁,锁定粒度大,发生锁冲突的概率最高,并发度低,适合多查询,少更新。 6. 行锁:偏向InnoDB存储引擎,开销大,枷锁慢,会出现死锁,锁定粒度小,发生锁冲突的概率低,并发度高。 8. 由于B+Tree只有叶子节点保存key信息,查询任何key都要从root走到叶子。所以B+Tree的查询效率更加稳定。MySql索引数据结构对经典的B+Tree进行了优化。在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能。 9. 为什么复合索引要遵循最左前缀法则? 10. 视图就是一条SELECT语句执行后返回的结果集(Oracle中有物化视图的概念)。视图优势:简单,安全,数据独立。 11. 存储引擎就是存储数据,建立索引,更新查询数据等等技术的实现方式 。存储引擎是基于表的,而不是基于库的。所以存储引擎也可被称为表类型。Oracle,SqlServer等数据库只有一种存储引擎。MySQL提供了插件式的存储引擎架构,比如说常用的InnoDB,MyISAM等。MySQL5.5之前的默认存储引擎是MyISAM,5.5之后就改为了InnoDB。 1. 使用共享表空间存储, 这种方式创建的表的表结构保存在.frm文件中, 数据和索引保存在 innodb_data_home_dir 和 innodb_data_file_path定义的表空间中,可以是多个文件。 2. 使用多表空间存储, 这种方式创建的表的表结构仍然存在 .frm 文件中,但是每个表的数据和索引单独保存在 .ibd 中。 12. MyISAM 不支持事务、也不支持外键,查询和插入速度比InnoDB快(表锁)表结构.frm,数据myd,索引.myi分开存储。 13. Mysql优化步骤: 1. 慢查询日志 : 通过慢查询日志定位那些执行效率较低的 SQL 语句,用--log-slow-queries[=file_name]选项启动时,mysqld 写一个包含所有执行时间超过 long_query_time 秒的 SQL 语句的日志文件。 2. show processlist命令查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操作进行优化。 3. 分析什么原因导致SQL执行缓慢:使用explain/desc SQL获取执行的详细信息,如:表的链接类型(性能由好到差的连接类型为:system ---> const -----> eq_ref ------> ref -------> ref_or_null----> index_merge ---> index_subquery -----> range -----> index ------> all),索引实际使用情况等信息。 14. 优化方法:利用索引,SQL语句优化,应用优化,查询缓存优化,内存管理优化。 15. 索引优化: 1. 建立合适的索引,复合索引。 2. 避免索引失效的场景:索引列上进行运算、字符串不加单引号、where后使用or、以%开头的模糊查询、not in、is null、is not null、where后使用!= <> 参数@num =等会造成索引失效。 3. 用exists 替换 in,尽量使用复合索引,不要使用select * 16. SQL语句优化: 1. 优化or条件,or两边都用索引。 17. 应用优化: 1. 使用连接池:对于访问数据库来说,`建立连接的代价是比较昂贵的`,因为我们频繁的创建关闭连接,是比较耗费资源的,我们有必要建立`数据库连接池`,以提高访问的性能。 1. 维护一定数量的链接减少创建时间 2. 更快的响应时间 3. 统一的管理 2. 减少对数据库的访问: 1. 能一条SQL解决的事情就不要两条; 2. 增加cache缓存层,现在主流的使用手段如:redis,MyBatis一二级缓存。 3. 负载均衡: 1. 利用某种均衡算法,将固定的负载量分布到不同的服务器上, 以此来降低单台服务器的负载,达到优化的效果。 2. MySQL的`主从复制`,实现读写分离,使增删改操作走主节点,查询操作走从节点,从而可以降低单台服务器的读写压力。 3. 采用分布式数据库架构 18. 查询缓存优化: 1. 客户端发送一条查询给服务器; 2. 服务器先会检查查询缓存,如果`命中`了缓存,则立即返回存储在缓存中的结果。否则进入下一阶段; 3. 服务器端进行SQL解析、预处理,再由优化器生成对应的执行计划; 4. MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询; 5. 将结果返回给客户端,并缓存起来 19. 内存管理优化:尽量多的内存分配给MySQL做缓存。 20. MySQL日志: 1. 错误日志.err 2. 查询日志和慢查询日志都是默认关闭的 3. 二进制日志记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但是不包括数据查询语句。此日志对于灾难时的数据恢复起着极其重要的作用,`MySQL的主从复制, 就是通过该binlog实现的。`默认是关闭的,需要手动开启mysqlbin.000001 4. binlog日志格式:STATEMENT(记录的都是SQL语句),Row(记录的是每一行的数据变更,而不是记录SQL语句),MIXED 5. mysqlbinlog [-vv] logfile查看日志 6. 日志删除: 1. `Reset Master 指令删除全部 binlog 日志`,删除之后,日志编号,将从 xxxx.000001重新开始 。 2. 执行指令 `purge master logs to 'mysqlbin.******'`,该命令将删除 `******`编号之前的所有日志。 3. 执行指令 `purge master logs before 'yyyy-mm-dd hh24:mi:ss'`,`该命令将删除日志为 "yyyy-mm-dd hh24:mi:ss" 之前产生的所有日志 。` 4. 设置参数 --expire_logs_days=n ,此参数的含义是设置日志的过期天数。 21. MYSQL主从复制:复制是指将主数据库的DDL 和 DML 操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。MySQL支持一台主库同时向多台从库进行复制, 从库同时也可以作为其他从服务器的主库,实现链状复制。 1. 步骤: 1. `Master 主库在事务提交时,会把数据变更作为时间 Events 记录在二进制日志文件 Binlog 中。` 2. `主库推送二进制日志文件 Binlog 中的日志事件到从库的中继日志 Relay Log 。` 3. `slave重做中继日志中的事件,将改变反映它自己的数据。` 2. 优势: 1. `主库出现问题,可以快速切换到从库提供服务。` 2. `可以在从库上执行查询操作,从主库中更新,实现读写分离,降低主库的访问压力。` 3. `可以在从库中执行备份,以避免备份期间影响主库的服务。` ## Oracle数据库 1. Oracle中使用rownum来进行分页, 这个是效率最好的分页方法。 2. 支持多用户、大事务量的事务处理,数据安全性和完整性控制,支持分布式数据处理,可移植性 3. Oracle实例:一个Oracle实例( Oracle Instance)有一系列的后台进程(Backguound Processes)和内存结构(Memory Structures)组成。 4. Oracle表空间:表空间是Oracle 对物理数据库上相关数据文件( ORA 或者 DBF 文件)的逻辑映射。 5. Oracle用户:用户是在表空间下建立的,用户:表空间=N:1。 6. JDBC 驱动为:`oracle.jdbc.OracleDriver` 7. 连接字符串( 瘦连接 ):`jdbc:oracle:thin:@IP:1521:orcl` 8. 序列是 ORACLE 提供的用于产生一系列唯一数字的数据库对象。 9. 表中的每一行在数据文件中都有一个物理地址,ROWID 伪列返回的就是该行的物理地址。 使用 ROWID 可以快速的定位表中的某一行。 10. 在查询的结果集中,ROWNUM 为结果集中每一行标识一个行号,第一行返回 1, 第二行返回 2,以此类推。 11. 索引是需要占据存储空间的,也可以理解为是一种特殊的数据。形式类似于 下图的一棵“树”,而树的节点存储的就是每条记录的物理地址,也就是我们提到的伪列( ROWID)。 12. Oracle数据迁移: 1. EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用。 2. EXPDP和IMPDP是服务端的工具程序,他们只能在ORACLE服务端使用,不能在客户端使用。 3. IMP只适用于EXP导出的文件,不适用于EXPDP导出文件;IMPDP只适用于EXPDP导出的文件,而不适用于EXP导出文件。 4. 创建具有导入导出数据库的权限的用户,创建目录对象,建立与远程Oracle服务器的DB_link,执行expdp命令导出xxx.dmp文件,将文件上传到目标Oracle的服务器上,执行impdp命令(指导目录对象,SCHEMA映射关系,表空间映射关系) ## 非关系型数据库—Redis 1. 关系型数据库和非关系型数据库有什么区别? 1. 关系型数据库最典型的数据结构是数据表,而非关系型数据库数据格式可以是Key-Value形式、文档形式、图片形式等。 2. 关系型数据库基于sql使用方便,支持事务,可以进行多个数据表的复杂管理操作,但是读写性能较差。 3. 非关系型数据库不支持sql,虽然说数据结构比较复杂,但是读写性能高(无需sql层的解析)常与关系型数据库进行关联使用。 2. Redis是以key-value的形式存储的非关系型数据库,分布式的,开源的,水平可扩展的,为了保证效率,数据都是缓存在内存中,它也可以周期性的把更新的数据写入磁盘或把修改操作写入追加的记录文件中。 3. Redis支持的五种数据类型:字符串类型String,哈希类型hash,列表类型lisst,集合类型set,有序集合类型sortedset 1. String:存储set key value ,获取get key,删除del key 2. hash:底层使用哈希表结构实现数据存储key(String)-value(HashMap),主要是用来存放一些对象,把一些简单的对象给缓存起来。 1. hash的成员比较少:value类似一维数组的方式来紧凑存储 2. hash的成员较多:value则自动转成真正的HashMap 3. 存储hset user name dd 3. list支持重复元素:key(String)-value(LinkedList),双向链表可以支持双向查找和变量。 1. 存储:lpush listname 1 2 3,rpush listname 1 2 3 2. 获取:lrange listname 0 -1 3. 删除:lpop/rpop listname 4. set不允许重复元素key(String)-value(Set),存储sadd setname 1 1 2 2,获取smembers setname,删除srem setname 1. 内部实现是一个value永远为null的HashMap,实际就是通过计算hash的方式来快速排重。 5. sortedset:元素不允许重复,根据score从小到大排序。存储zadd key(score value)可以由多个,获取 zrange key start end 删除 zrem key value 1. 内部使用HashMap(score)和跳跃表(skiplist)来保证数据的存储和有序。 6. keys * 查询所有的键,type key,del key 4. Redis持久化方式RDB(默认-定时快照方式)和AOP(基于语句追加文件的方式)的区别: 1. RDB:默认方式,不需要进行配置,默认就使用这种机制 2. AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据在一定的间隔时间中,检测key的变化情况,然后持久化数据。 3. 相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积; 5. Redis可以通过 maxmemory 参数来限制最大可用内存,主要为了避免Redis内存超过操作系统内存,从而导致服务器响应变慢甚至死机的情况。 6. ~~~~java //使用Redis有哪些好处? a.单线程,利用redis队列技术并将访问变为串行访问,消除了传统数据库串行控制的开销 b.redis具有快速和持久化的特征,速度快,因为数据存在内存中。 c.分布式 读写分离模式 d.支持丰富数据类型 e.支持事务,操作都是原子性,所谓原子性就是对数据的更改要么全部执行,要不全部不执行。 f.可用于缓存,消息,按key设置过期时间,过期后自动删除 //缺点:缓存与数据库双写不一致,缓存雪崩,缓存穿透 ~~~~ ## JVM 1. 懂得JVM内部的内存结构、工作机制,是设计高扩展性应用和诊断运行时问题的基础,也是Java工程师进阶的必备能力。 2. JVM字节码包含了Java虚拟机指令集(或者称为字节码、Bytecodes)和符号表,还有一些其他辅助信息。 3. `虚拟机可以分为系统虚拟机和程序虚拟机:典型代表就是Java虚拟机`,Java技术的核心就是Java虚拟机(JVM) ,因为所有的Java程序都运行在Java虚拟机内部。 4. `HotSpot VM是目前市面上高性能虚拟机的代表作之一。`它采用`解释器与即时编译器并存`的架构。 5. Java编译器输入的指令流基本上是一种`基于栈的指令集架构`,特点:指令集更小,编译器容易实现。不需要硬件支持,可移植性更好,更好实现跨平台。 6. 了解JVM的发展历程:Classic VM(只有解释器,JDK1.4被淘汰)-->Exact VM(准确式内存管理,编译与解释混合工作)-->`HotSpot VM`(JDk1.3开始,具有热点代码探测技术) -->JRockit VM(JDK89中整合到HostspotVM中)-->J9-->Taobao JVM(基于openJDK HotSpot VM发布的国内第一个优化、深度定制且开源的高性能服务器版Java虚拟机。创新的GCIH (GC invisible heap)技术实现了off-heap ,即将生命周期较长的Java对象从heap中移到heap之外,并且GC不能管理GCIH内部的Java对象,以此达到降低GC的回收频率和提升Gc的回收效率的目的,但是硬件严重依赖intel的cpu。) 1. 通过计数器找到最具编译价值代码,触发即时编译或栈上替换 2. 通过编译器与解释器协同工作,在最优化的程序响应时间与最佳执行性能中取得平衡 7. 字节码文件:-->类加载器子系统(加载,链接[验证,准备,解析],初始化)-->运行时数据区(方法区,堆空间,栈空间,PC寄存器,本地方法栈)-->执行引擎(解释器,JIT即时编译器) 1. 加载阶段-双亲委派机制: - 基础概念:引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)-->将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器。 - 引导类加载器 Bootstrap ClassLoader:只加载包名为java、javax、sun等开头的类。 - 扩展类加载器 Extension ClassLoader:目录的jre/1ib/ext子目录(扩展目录)下加载类库 - 系统类加载器 App ClassLoader:加载环境变量classpath或系统属性java.class.path指定路径下的类库 2. 工作原理: 1. 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行; 2. 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器; 3. 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。 3. 好处:避免类的重复加载,保证程序安全,防止核心API被随意更改。 4. 沙箱安全机制:自定义String类,但是在加载自定义String类的时候会率先使用引导类加载器加载。 5. 在JVM中表示两个class对象是否为同一个类存在两个必要条件: 1. 类的完整类名必须一致,包括包名。 2. 加载这个类的ClassLoader(指ClassLoader实例对象)必须相同 6. 链接阶段--验证--解析--准备 1. 验证阶段: 1. 文件格式验证,元数据验证,字节码验证,符号引用验证。 2. 解析阶段: 1. 为`类变量`分配内存并且设置该类变量的默认初始值,即零值。 2. `这里不包含用final修饰的static,因为final在编译的时候就会分配了,准备阶段会显式初始化;` 3. 准备阶段:将常量池内的符号引用转换为直接引用的过程。 7. 初始化阶段: 1. 执行类构造器方法`()`的过程:☆javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。☆只有类变量才有方法。 8. 我们把大厨后面的东西(切好的菜,刀,调料),比作是运行时数据区。而厨师可以类比于执行引擎。 9. 线程私有(程序计数器,虚拟机栈[栈帧(局部变量表,操作栈,动态链接,方法返回地址)],本地方法栈; 10. `线程间共享:堆、堆外内存(永久代或元空间[常量池,方法元信息,类源信息]、代码缓存)` 11. 在Hotspot JVM里,每个线程都与操作系统的本地线程直接映射。 12. JVM系统线程:虚拟机线程,周期任务线程,GC线程,编译线程,信号调度线程。 13. 程序计数器作用: 1. 单线程:字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制。 2. 多线程:用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。 14. 虚拟机栈(通过-Xss1m设置栈空间大小):栈帧的大小主要由局部变量表和操作数栈决定的。 1. 局部变量表所需的容量大小是在编译期确定下来的,主要用于存储方法参数和定义在方法体内的局部变量这些数据类型包括各类基本数据类型、对象引用(reference),以及returnAddress类型。 2. 当一个实例方法被调用的时候,它的方法参数和方法体内部定义的局部变量将会按照顺序被复制到局部变量表中的每一个变量槽slot(32位一个槽)上。 3. 如果当前帧是由构造方法或者实例方法创建的,那么`该对象引用this将会存放在index为0的变量槽Slot处,`其余的参数按照参数表顺序继续排列。 4. HotSpot JVM的设计者们提出了`栈顶缓存(Tos,Top-of-Stack Cashing)技术`,将栈顶元素全部缓存在物理CPU的寄存器中,以此降低对内存的读/写次数,提升执行引擎的执行效率。 5. 动态链接: 1. `在Java源文件被编译到字节码文件中时,所有的变量和方法引用都作为符号引用(symbolic Reference)保存在class文件的常量池里。` 2. 动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用。 3. ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200915193938847.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTI2NzEwMg==,size_16,color_FFFFFF,t_70#pic_center) 6. 方法返回地址:存放调用该方法的pc寄存器的值 15. `在Hotspot JVM中,直接将本地方法栈和虚拟机栈合二为一。` 16. “几乎”所有的对象实例以及数组都应当在运行时分配在堆上。堆在逻辑上JDK1.7(新生代,老年代,永久代),JDK1.8(新生代,老年代,元空间) 17. 通常会将-Xms(memory start)和-Xmx两个参数配置相同的值,其目的是为了能够在Java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小,从而提高性能。 1. `初始内存大小:物理电脑内存大小/64;` 2. `最大内存大小:物理电脑内存大小/4;` 3. -XX:+PrintGCDetails 18. `年轻代(Eden:Survivor0:Survivor):老年代=1(8:1:1):2`,from区、to区,复制之后有交换,谁空谁是to。。 19. `当发现在整个项目中,生命周期长的对象偏多,那么就可以通过调整 老年代的大小,来进行调优。` 20. `几乎所有的Java对象都是在Eden区被new出来的。`绝大部分的Java对象的销毁都在新生代进行了。`(有些大的对象在Eden区无法存储时候,将直接进入老年代)` - `IBM公司的专门研究表明,新生代中80%的对象都是“朝生夕死”的。` 21. 当老年代内存不足时,再次触发GC:`Major GC`,进行老年代的内存清理。若老年代执行了Major GC之后,发现依然无法进行对象的保存,就会产生OOM异常 22. 如果Survivor区满了后,不会触发MinorGC操作,将会触发`一些特殊的规则`,也就是可能直接晋升老年代 1. 如果 Survivor 空间中相同年龄所有对象大小的总和大于 Survivor 空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无需达到要求的年龄。 23. 当年轻代空间不足时,就会触发Minor GC 24. 出现了Major GC,经常会伴随至少一次的Minor GC,如果Major GC后,内存还不足,就报OOM了。 25. `由Eden区、survivor space0(From Space)区向survivor space1(To Space)区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。`会触发Full GC 26. 70%-99%的对象是临时对象。 27. 分代的唯一理由就是优化GC性能 28. 大对象直接分配到老年代,因为如果在from/to间来回复制消耗性能。 29. `TLAB`,也就是为每个线程单独分配了一个缓冲区。 1. JVM为每个线程分配了一个私有缓存区域,它包含在Eden空间内 2. 尽管不是所有的对象实例都能够在TLAB中成功分配内存,但JVM确实是将TLAB作为内存分配的首选(联想对象的创建过程) 3. 默认情况下TLAB是开启的,TLAB空间的内存非常小,`仅占有整个Eden空间的1%` 30. JDK6 Update 24之后的规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC,否则将进行Full GC。 31. 如果经过逃逸分析(Escape Analysis)后发现,一个对象并没有逃逸出方法的话,那么就可能被优化成栈上分配。 32. 逃逸分析的基本行为就是`分析对象动态作用域`: - `当一个对象在方法中被定义后,对象只在方法内部使用,则认为没有发生逃逸,则可以在栈上分配。` - 当一个对象在方法中被定义后,它被外部方法所引用,则认为发生逃逸。例如作为调用参数传递到其他地方中。 - 开发中能使用局部变量的,就不要使用在方法外定义。 - 逃逸分析无法保证逃逸分析的性能消耗一定能高于他的消耗。 33. Person(方法区) person(Java栈) = new Person()Java堆;方法区主要存放的是 Class,而堆中主要存放的是实例化的对象。 34. `在jdk7及以前,习惯上把方法区,称为永久代。jdk8开始,使用元空间取代了永久代,并且元空间存放在堆外内存中。`,使用永久代容易出现OOM,因为永久代的空间大小不好配置。元空间使用本地内存。 35. 内存泄漏就是 有大量的引用指向某些对象,但是这些对象以后不会使用了,但是因为它们还和`GC ROOT`有关联,所以导致以后这些对象也不会被回收,这就是内存泄漏的问题。 1. 如果是内存泄漏,`可进一步通过工具查看泄漏对象到GC Roots的引用链。`于是就能`找到泄漏对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收它们的。`掌握了泄漏对象的类型信息,以及`GC Roots引用链的信息`,就可以比较准确地定位出泄漏代码的位置。 36. 方法区:它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。 37. | JDK1.6及以前 | 有永久代,静态变量存储在永久代上 | | ------------ | ------------------------------------------------------------ | | JDK1.7 | 有永久代,`但已经逐步 “去永久代”,字符串常量池,静态变量移除,保存在堆中` | | JDK1.8 | `无永久代`,类型信息,字段,方法,常量保存在本地内存的元空间,但字符串常量池、静态变量仍然在堆中。 | ## 前端-HTML 1. 明白Web,网页,网站,Web前端,后端,Html(超文本标记语言),CSS(层叠样式表),JavaScript(直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。),TypeScript,浏览器内核,字符集(编码解码)等概念; ~~~~html 网页的标签 超链接(默认是_self)... 超链接... 超链接...

段落标签1

段落标签2

标题标签h1

标题标签h6
标题标签h7(正常文本)
div双标签
字体标签 加粗的新老标签 倾斜新老标签 下划线新老标签 删除新老标签

  • 无序列表
  • 无序列表
  1. 有序列表
  2. 有序列表
dt
dd
表格的标题
表头1 表头2
a b
~~~~ 2. 表格的属性: 1. cellspacing: 单元格之间的距离,默认的是 2px 1. 如果设置为0px,还需要设置`border-collapse:collapse; `相邻边框合并在一起。 2. cellpadding:单元格的内边距,默认 1px 3. width:设置表格的宽度 4. height:设置表格的高度 5. align:设置水平偏移 center ,left ,right 6. border:设置表格的边框 3. 块级元素(div,h1-h6,hr,p,ul,li,ol,li,dl,dt,dd),行内元素(span,strong,del,ins,em,a),行内块级元素。 1. display: inline/inline-block/block设置盒子的display样式去让盒子变成任何盒子的展示模式。 4. 特殊字符:空格` ` ## 前端-CSS&动画 1. 了解CSS的三种书写方式: 1. 行内式:`
青春不常在,抓紧谈恋爱
` 2. 内部样式表:`` 3. 外部样式表: ` ` 2. CSS选择器:有标签选择器div,类选择器`.类名`(一个标签可以设置多个类属性,使用空格分隔),id选择器`#id`(元素的id值是唯一的,只能对应于文档中某一个具体的元素),通配符选择器`*`。 1. 复合选择器:后代选择器`.class h3`,子元素选择器`.class>h3`,链接的伪类选择器`(a:link a:visited a:hover a:active)`lvha 的顺序不可变。 2. 相临兄弟选择器:`元素+相邻兄弟元素;` 3. 通用兄弟选择器:`元素~后面所有兄弟元素;` 4. 群组选择器:`元素1,元素2;` 5. 属性选择器:element[attribute] 为带有attribute属性的元素设置样式:li[title]选择拥有title属性的li标签。 1. `li[title='ddaimm']`为title='ddaimm'属性的元素设置样式。 2. `~=`包含,`^=`以这个值开头,`$=`以这个为结尾,`*=`包含值得所有元素。 6. CSS3结构类: 1. `li:first-child{}`选择li标签父元素的第一个孩子元素,如果该元素是li标签,那么触发下面的样式。 2. `li:last-child{}`选择li标签父元素的最后一个孩子元素,如果该元素是li标签,那么触发下面的样式。 3. `li:nth-child(3)`,从1开始 1. li:nth-child(even)偶数,li:nth-child(odd)奇数; 2. li:nth-child(2n+1)n的值是从0开始,每次加1,只能是n。 3. li:nth-last-child(2)选择li标签父元素的倒数第二个孩子元素,如果该元素是li标签,那么触发下面的样式。 4. `li:first-of-type,li:last-of-type` 5. `li:nth-of-type(3)`匹配属于父元素的特定类型的第n个子元素 1. li:nth-of-type(even),li:nth-of-type(odd),li:nth-of-type(3n+1) 6. li:only-child匹配属于其父元素的唯一子元素的每个元素 7. li:only-of-type匹配属于其父元素特定类型的唯一子元素的每个元素 8. span:empty匹配没有子元素(包括文本节点)的每个元素 7. 否定选择器`ul :not(span)`前面有空格,指的是ul标签下面的所有子标签。 3. 通过CSS设置字体的样式:`font-size: 16px/1em;`,`font-family:“微软雅黑”;`开发中可以使用unicode编码设置字体,`font-weight: normal/bold/400/700;`,`font-style: normal/italic;` 1. 字体样式的连写:`选择器 { font: font-style font-weight font-size/sline-height font-family;}`,不能更换顺序,但必须保留font-size和font-family属性。 4. 文本水平对齐方式`color: red/#90ee90/rgb/rgba;`,文本水平对齐方式`text-align: left/right/center;`,行间距`line-height: 16px/2em;`,首行缩进`text-ident: em;`,文本的修饰`text-decoration: none/underline/overline/line-through;` 5. | 元素模式 | 元素排列 | 设置样式 | 默认宽度 | 包含 | | ------------ | ---------------------- | ---------------------- | ---------------- | ------------------------ | | `块级元素` | 一行只能放一个块级元素 | 可以设置宽度高度 | 容器的100% | 容器级可以包含任何标签 | | `行内元素` | 一行可以放多个行内元素 | 不可以直接设置宽度高度 | 它本身内容的宽度 | 容纳文本或则其他行内元素 | | `行内块元素` | 一行放多个行内块元素 | 可以设置宽度和高度 | 它本身内容的宽度 | | 1. 行内元素为了照顾兼容性, 尽量只设置左右内外边距, 不要设置上下内外边距。 6. CSS背景的设置:`background-color: #90ee90;`,`background-image: none/url;`url(多个url使用,分隔)不加引号,`background-repeat: repeat/no-repeat/repeat-x/repeat-y;`背景平铺,`background-position: x|y(top/right/bottom/left/center);`背景位置需要基于背景位置,`background-attachment: scroll/fixed;`背景附着; 1. 背景简写:background: 背景颜色 背景图片地址 背景平铺 背景滚动 背景位置; 2. `background: transparent url(image.jpg) repeat-y scroll center top ;` 3. `background: rgba(0,0,0,0.3);`==背景==透明。 4. background-clip设置元素的背景(背景图片或颜色)是否延伸到边框border-box、内边距盒子padding-box、内容盒子下面content-box。 5. `background-size:cover/contain;`设置图片大小,cover默认查找最远边,contain默认查找最近边。 6. 7. 行高`line-height: x%/ypx;`,基线和基线的距离; 8. CSS三大特性:层叠性(长江后浪推前浪,前浪死在沙滩上),继承性(子承父业),优先级(谁的权重大,谁生效); 1. | 继承的权重是 | 0 | | ----------------------------- | ------ | | 标签选择器的权重是/元素选择器 | 1 | | 类选择器的权重是 | 10 | | id选择器的权重是 | 100 | | 行内样式的权重是 | 1000 | | !important 权重是 | 无穷大 | 9. 盒子模型有元素的内容、边框(border)、内边距(padding)、和外边距(margin)组成。 1. 边框:`border: 1px solid/dashed/dotted/none red;`,还可以使用`border-top/border-top-stype;` 2. 内边距:`padding: 上% 右px 下% 左px;`(一个值就是上右下左),如果没有给一个盒子指定宽度, 此时,如果给这个盒子指定padding, 则不会撑开盒子,相反如果设置了宽高盒子会被撑大。也可以使用`padding: 上下内边距 左右内边距;`,`padding-left: 16px;` 3. `盒子的实际的大小 = 内容的宽度和高度 + 内边距 + 边框。` 4. 外边距: 使用方法同padding,margin就是控制盒子和盒子之间的距离。 1. 相邻块元素垂直外边距的合并,俩盒子垂直间距不是margin-bottom与margin-top之和 取两个值中的较大者这种现象被称外边距塌陷。 10. 块级盒子水平居中:一、设置盒子的宽高;二、左右外边距设置atuo。盒子内的文字水平居中是`text-align: center;`, 而且还可以让行内元素和行内块居中对齐。 11. 盒子模型布局稳定性:`优先使用 宽度 (width) 其次 使用内边距(padding)再次 外边距(margin)`。 12. 扩展: 1. 去除有序列表和无序列表的默认样式:`list-style:none;` 2. 圆角边框:`border-radius: 16px/50%;` 3. 盒子阴影:`box-shadow: 5px 5px 3px 4px rgba(0, 0, 0, .4);` 1. `box-shadow:水平阴影 垂直阴影 模糊距离(虚实) 阴影尺寸(影子大小) 阴影颜色 内/外阴影;` 13. 盒子浮动float: 1. CSS三种布局方式:标准流,浮动(让多个块级盒子一行显示),定位。 2. 行内块(inline-block) 可以实现多个元素一行显示,但是中间会有空白缝隙,也不能实现以上第二个问题,盒子左右对齐; 3. 元素的浮动`float:left/right/none;`是指`设置了浮动属性的元素`会:脱离标准普通流的控制,移动到指定位置。 4. float属性会改变元素display属性。浮动元素会生成一个块级框,生成的块级框和我们前面的行内块极其相似。 5. 浮动元素与父盒子的关系:子盒子的浮动参照父盒子对齐,不会与父盒子的边框重叠,也不会超过父盒子的内边距。 6. `浮动只会影响当前的或者是后面的标准流盒子,不会影响前面的标准流。` 7. 清除浮动`clear:left/right/both;`主要为了解决父级元素因为子级浮动引起内部高度为0 的问题。清除浮动之后, 父级就会根据浮动的子盒子自动检测高度。父级有了高度,就不会影响下面的标准流了 1. 是W3C推荐的做法是通过在浮动元素末尾添加一个空的标签例如 `
`,或则其他标签br等亦可。 2. 父级添加`overflow:hidden/auto/scroll;`属性方法。就是内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素。 3. :after 方式为空元素额外标签法的升级版,好处是不用单独加标签了。减轻了浏览器的渲染负担,所以考虑使用伪元素 :after 来代替这个空白标签,因为清除浮动需要在浮动元素后面,所以不可以使用 :before ,对 :after 设置 content:"" ,并使其 display:block 成为块级元素后 clear:both 来清除浮动。 14. 定位:将盒子定在某一个位置 自由的漂浮在其他盒子(包括标准流和浮动)的上面 。 1. `定位 = 定位模式 + 边偏移` 2. 定位模式:`position:static/relative/absolute/fixed;`静态/相对/绝对/固定定位。 1. 静态定位就是无定位的意思; 2. `相对定位`是元素`相对`于它原来在标准流中的位置来说的。原来在标准流的区域继续占有,后面的盒子仍然以标准流的方式对待它。 3. `绝对定位`是元素以带有定位的父级元素来移动位置,完全脱标 —— 完全不占位置,父元素没有定位,则以浏览器为准定位(Document 文档)。 1. `子绝父相` —— `子级`是`绝对`定位,`父级`要用`相对`定位,因为==父级要占有位置,子级要任意摆放==。 4. `固定定位`是`绝对定位`的一种特殊形式,完全脱标,只认`浏览器的可视窗口` —— `浏览器可视窗口 + 边偏移属性` 来设置元素的位置。 3. 绝对定位的盒子居中:`position:absolute;left:50%;margin-left:-weigthpx;` 4. `z-index` 层叠等级属性可以`调整盒子的堆叠顺序`,`正整数`、`负整数`或 `0`,默认值是 0,数值越大,盒子越靠上;`z-index` 只能应用于`相对定位`、`绝对定位`和`固定定位`的元素。 15. `box-sizing: content-box/border-box;`默认是content-box 1. ![img](https://img-blog.csdnimg.cn/20201031170528467.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTI2NzEwMg==,size_16,color_FFFFFF,t_70#pic_center) 2. ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201031170539597.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTI2NzEwMg==,size_16,color_FFFFFF,t_70#pic_center) 16. 伪元素:div::first-line第一行,div::first-letter第一个字母,div::before,div::after在元素的内容前/后面插入新内容,常与content配合使用,div::selection用于设置浏览器中选中文本后的背景色与前景色。 1. 伪元素无法通过JS获取其DOM,无法通过浏览器直接查看,伪元素默认是 inline 17. 边框圆角(块元素,行内块元素,行内元素):`border-radius:%/px;`,一个值4个角都生效。可以制作八卦图,大风车。 1. 两个值:左上角和右下角 右上角和左下角 2. 三个值:左上角 右上角和左下角 右下角 3. 四个值:左上角 右上角 右下角 左下角 18. 文字阴影text-shadow,可以实现文字阴影,浮雕文字,文字描边,文字排版等。 ```css /*text-shadow: 水平方向的偏移量,垂直方向的偏移量,模糊程度,阴影的颜色。*/ text-shadow:6px -6px 2px lightgreen,7px -7px 1px lightpink; /*字间距*/ letter-spacing: 10px; /*描边*/ -webkit-text-stroke: 4px deeppink; /*文字方向:ltr/rtl*/ direction:rtl; ``` 19. 盒子阴影:box-shadow,可以实现立体球等效果。 ~~~css /* box-shadow:水平方向的偏移量,垂直方向的偏移量,模糊程度,扩展程度,盒子阴影的颜色,inset 内阴影*/ box-shadow:5px -5px 10px 10px rgba(88,255,99,1) inset; /*不设置inset为外阴影,为一个盒子设置多给阴影使用“,”隔开*/ /*box-reflect : 倒影的方向(above below left right ) 倒影与元素之间的距离 倒影效果(线性渐变)*/ -webkit-box-reflect:below 10px linear-gradient(0deg,rgba(0,0,0,1),rgba(0,0,0,0)); /*横向拉动长短*/ resize:horizontal; /*纵向拉动长短*/ resize:vertical; /*拉动横向和纵向长短*/ resize:both; ~~~ 20. 背景模糊(图片文字都可以)`filter:blur(5px);` 21. 渐变gradient: 1. 线性渐变`background-image:linear-gradient(方向,颜色,颜色);` 1. 方向有:to right,to top,to top right,to bottom left,60deg等; 2. `background: linear-gradient(red 10%,blue 20%,green 30%,yellow 40%);` 3. `background:linear-gradient(to right,red 25%, blue 25%, blue 50%,green 50%, green 75%, yellow 75%);` 2. 径向渐变`background:radial-gradient(circle/ellipse,颜色,颜色);` 22. 过度`transition: property duration timing-function delay;`时间顺序不能乱,其他参数位置不限,如果想给多个属性添加不同的过度,参数之间使用逗号分开。 1. `transition-property: none/all/property;` 2. `transition-duration: 2s/2000ms;` 3. transition-timing-function: 1. linear:线性过渡(匀速)cubic-bezier(0,0,1,1) 2. ease:平滑过渡(慢--快--慢),默认值 cubic-bezier(0.25,0.1,0.25,1) 3. ease-in:慢--快 cubic-bezier(0.42,0,1,1) 4. ease-out:快--慢 cubic-bezier(0,0,0.58,1) 5. ease-in-out:慢--快--慢 cubic-bezier(0.42,0,0.58,1) 4. `transition-delay: 2s/2000ms;` 23. 变换transform: 1. 2D变换:变换基点transform-origin:水平方向 垂直方向,可以使用top和%、px; 1. 旋转rotate:`transform: rotate(45deg);`如果是正数,顺时针旋转,如果是负数,逆时针旋转。 2. 平移translate:`transform: translate(xpx,ypx)/translateX(xpx)/translateY(ypx);` 3. 缩放scale:`transform: scale(0.5,2)/scale(0.5)/scale(2);` 4. 倾斜skew:`transform: skew(xdeg,ydwg)/skew(xdeg)/skew(ydeg);` 2. 3D变换:开启3D变换`transform-style: preserve-3d;`,一般对父元素设置。 1. 设置景深:`perspective: 300px;`实现元素在3D空间中的近大远小的效果,景深值越大,效果越不明显,越接近2d变换。 2. 变换基点transform-origin:默认是`50% 50% 0`,Z轴只能使用具体的长度。 3. 景深中心点:`perspective-origin: top right;`改变观察者视角 4. 改变观察者视角:`backface-visibility: visible/hidden;`(默认值:可见) 5. 变换设置: 1. rotateX():指对象在X轴上的旋转角度(变换基点: 50% 50% 0) 2. rotateY():指对象在Y轴上的旋转角度(变换基点: 50% 50% 0) 3. rotateZ():指对象在Z轴上的旋转角度(变换基点: 50% 50% 0) 4. translateZ():指对象在Z轴上面的平移(变换基点: 50% 50% 0) 5. scaleZ():指对象在Z轴上面的缩放(变换基点: 50% 50% 0) 24. 动画animation:`@keyframes animation-name{0%{}100%{}};`,结合着变换和精灵图可以实现很多有意思的动画。 1. `animation-name: 动画名称;` 2. `animation-duration: 5s;`动画持续时间 3. `animation-timing-function:` 动画的过渡类型,处理可以设置一下内容还可以使用steps(x); 1. linear:线性过渡(匀速) 2. ease:平滑过渡(0--慢--快--慢),默认值 3. ease-in:慢--快 4. ease-out:快--慢 5. ease-in-out:慢--快--慢 4. `animation-delay:2s;`动画的延迟时间 5. `animation-iteration-count:infinite;`动画循环次数 6. `animation-direction:normal/reverse/alternate/alternate-reverse;` 7. `animation-play-state:paused/running;`动画运行的状态 8. `animation-fill-mode:backwards/forwards/both;`设置对象动画外的状态 9. `animation: name duration timing-function delay interation-count direction play-state;` 25. 伸缩盒子模型flex:flex布局原理就是通过给父盒子添加flex属性,来控制子盒子的位置和排列方式。开启flex布局:`display: flex;` 1. flex容器的常用属性: 1. `flex-direction: row/row-reverse/column/column-reverse;`设置flex布局的主轴; 2. `justify-content: flex-start/flex-end/center/space-around/space-between;`设置主轴上的子元素的排列方式; 3. `flex-wrap:nowrap/wrap;`子元素是否换行,默认不换行; 4. `align-items: flex-start/flex-end/center/stretch;`设置侧轴上的子元素的排列方式(只能在子元素单行时设置); 5. `align-content: flex-start/flex-end/center/space-around/space-between/stretch;`设置侧轴上的子元素的排列方式(只能在子元素多行时设置) 6. `flex-flow: flex-direction flex-wrap;f`lex主轴金和子元素是否换行的复合属性; 2. flex子项的常用属性: 1. `flex: 2;`flex属性定义子项目分配剩余空间,用flex来表示占多少份数默认是0; 2. `align-self: flex-start/flex-end/center;` 控制子项自己在侧轴上的排列方式; 3. `order: -1;`属性定义项目的排列顺序,数值越小,排列越靠前,默认为0。 26. 语义化标签布局: 1. ![image-20211024173227138](assets/image-20211024173227138.png) 27. 多媒体: 1. 音频audio: 2. 视频video: 28. Canvas ## 前端-JavaScript 1. 什么是JS:一种`直译式解释脚本语言`,动态类型、弱类型、基于原型的语言,内置支持类型。 2. JS的组成:ECMA,BOM,DOM 3. 声明变量使用:var、val、let;变量命名同Java,Python声明变量直接写。在JS中使用var定义的变量,会存在变量提升。 4. JS数据类型:number,string.length,boolean,==object==,undefined,Symbol,Null 5. JS运算符和赋值运算符同Java,JS特有的比较运算符 `==等于 ===等值类型 != !==`,注意for循环中的声明变量,声明数组`var arr = [1,2,3,4,"hahah"]`,数组的遍历arr.length,JS也支持面向对象。 6. 常用函数parseInt(),console.log(),typeof(),instanceof(),document.write() 7. ~~~~javascript // 自定义函数 function haha(param1,param2){ /*方法体;*/ return xxx; } // 匿名函数 var haha = function(param1,param2){}() ~~~~ 8. JSON(JavaScript Object Notation, JS 对象简谱)是一种轻量级的数据交换格式。它基于 ECMAScript(欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。 9. JS常用对象: 1. JSON对象:`var zhangsan={"name":"张三","age":19,"sex":"男"}` 1. JSON.parse(.json)转成JSON对象 2. JSON.stringify(json对象)解析成json串 2. Date对象,其中一些getXXX()方法; 3. Math对象的常用方法:abs(),ceil(),round(),max(),min(),pow(2,3),random()[0,1) 4. 字符串常用方法:charAt(),concat(),indexOf(),lastIndexOf(),replace(),substring(),split(),trim(),toLocaleLowerCase() 5. 数组常用方法:push(),pop(),unshift(),reverse(),slice(),splice(),sort(fun) 10. 11. ## 前端-jQuery ## 前端-Vue ## Web基础 1. 明白JDBC整个流程,软件架构C/S和B/S结构的区别,以及静态资源和动态资源的概念,还有网络通信的三要素: 1. 传输协议:规定了数据传输的规则。 - tcp协议:有连接,安全协议,三次握手。速度慢。 文件传输。 - udp协议:无连接,不安全协议。 直播,点播,广播。 2. ip地址:电子设备(计算机)的在网络中的唯一标识。 3. 端口号:应用程序在电子设备(计算机)中的位置标识。 2. 明白web服务器(安装了服务器软件的计算机),web服务器软件(接收用户的请求,处理请求,响应结果)的概念。常见的web服务器软件有:tomcat中小型,weblogic大型,websphere大型,JBoss大型。 3. tomcat和nginx的区别: 1. nginx常用做静态内容服务和代理服务器,直接外来请求转发给后面的应用服务器; 2. tomcat更多用来做一个应用的容器;将项目直接放到webapps文件夹中,可以直接放web应用文件,也可以放web应用的war包,tomcat启动时,会自动解压war包; 4. servlet接口,定义了Java类如何能够被浏览器访问到的规范。自定义类(servlet对象在第一次被访问到的时候创建,load-on-startup>=0时tomcat启动时创建)实现servlet接口重写 1. init()方法:servlet对象被创建的时候,执行init方法。 2. service()方法:每次访问servlet的时候,service方法就会被调用一次; 3. destory()方法:只有正常关闭服务器的时候,才会执行destory方法,一般用来关闭资源; 4. 编写web.xml中的servlet和servlet-mapping 5. 执行原理: 1. 浏览器发送请求:http://localhost:8080/hello 2. 服务器接收到请求后,解析url地址,要去找到对象的servlet,然后执行他的service方法 3. 服务器在加载web.xml的时候,会去解析servlet-mapping中的url-pattern的路径 4. 如果找到的对应的路径,根据路径找到servlet-class的全类名 5. tomcat将当前的class文件加载到内存中,并且创建它的对象 6. 调用servlet中的service方法 5. Servlet3.0(WEB3.0)算是比较新的Servlet技术了,对应版本JDK7,Servlet3.0的配置步骤:定义一个servlet类,实现servlet接口,重写方法,使用注解配置(可以省略web.xml不写): ~~~java @WebServlet(urlPatterns = {"/student","/student1"},loadOnStartup = 1) @WebServlet("/mm") public class HelloServlet implements Servlet{ //重写Servlet方法 } ~~~ 6. ## Spring ## SpringMVC ## MyBatis ## MyBatisPlus&Jpa ## SpringBoot ## SpringClould # 是什么? # 怎么用? # 怎么用好? # 为什么这样用就好呢? # 软件架构 [Linux笔记](https://gitee.com/duanchaojie/java-code/tree/master/0%E3%80%81Linux%E7%AC%94%E8%AE%B0) [数据结构与算法](https://gitee.com/duanchaojie/java-code/tree/master/1%E3%80%81%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95) - [力扣刷题总结](https://gitee.com/duanchaojie/java-code/tree/master/1%E3%80%81%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/%E5%8A%9B%E6%89%A3%E5%88%B7%E9%A2%98%E6%80%BB%E7%BB%93) 前端[代码](https://gitee.com/duanchaojie/java-code/tree/master/2%E3%80%81%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E4%BB%A3%E7%A0%81)和[笔记](https://gitee.com/duanchaojie/java-code/tree/master/2%E3%80%81%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E7%AC%94%E8%AE%B0) - [HTML和CSS](https://gitee.com/duanchaojie/java-code/tree/master/2%E3%80%81%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E7%AC%94%E8%AE%B0) - [JavaScript](https://gitee.com/duanchaojie/java-code/tree/master/2%E3%80%81%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E7%AC%94%E8%AE%B0/%E5%89%8D%E7%AB%AF-JavaScript) - [JQuery](https://gitee.com/duanchaojie/java-code/tree/master/2%E3%80%81%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E7%AC%94%E8%AE%B0/%E5%89%8D%E7%AB%AF-JQuery) - [Vue](https://gitee.com/duanchaojie/java-code/tree/master/2%E3%80%81%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E7%AC%94%E8%AE%B0/%E5%89%8D%E7%AB%AF-Vue) JavaSE[代码](https://gitee.com/duanchaojie/java-code/tree/master/3%E3%80%81Java%E5%9F%BA%E7%A1%80%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/code)和[笔记](https://gitee.com/duanchaojie/java-code/tree/master/3%E3%80%81Java%E5%9F%BA%E7%A1%80%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/note) - [JavaSE](https://gitee.com/duanchaojie/java-code/tree/master/3%E3%80%81Java%E5%9F%BA%E7%A1%80%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/note/JavaSE) - [JavaSE-IO流](https://gitee.com/duanchaojie/java-code/tree/master/3%E3%80%81Java%E5%9F%BA%E7%A1%80%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/note/JavaSE-IO%E6%B5%81) - [JavaSE-JVM](https://gitee.com/duanchaojie/java-code/tree/master/3%E3%80%81Java%E5%9F%BA%E7%A1%80%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/note/JavaSE-JVM) - [JavaSE-多线程](https://gitee.com/duanchaojie/java-code/tree/master/3%E3%80%81Java%E5%9F%BA%E7%A1%80%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/note/JavaSE-%E5%A4%9A%E7%BA%BF%E7%A8%8B) - [JavaSE-集合](https://gitee.com/duanchaojie/java-code/tree/master/3%E3%80%81Java%E5%9F%BA%E7%A1%80%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/note/JavaSE-%E9%9B%86%E5%90%88) - [JavaSE-设计模式](https://gitee.com/duanchaojie/java-code/tree/master/3%E3%80%81Java%E5%9F%BA%E7%A1%80%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/note/JavaSE-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F) JavaWeb[代码](https://gitee.com/duanchaojie/java-code/tree/master/4%E3%80%81JavaWeb%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E4%BB%A3%E7%A0%81)和[笔记](https://gitee.com/duanchaojie/java-code/tree/master/4%E3%80%81JavaWeb%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E7%AC%94%E8%AE%B0) [MySQL数据库笔记](https://gitee.com/duanchaojie/java-code/tree/master/5%E3%80%81MySQL%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AC%94%E8%AE%B0) - [MySQL基础](https://gitee.com/duanchaojie/java-code/tree/master/5%E3%80%81MySQL%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AC%94%E8%AE%B0/MySQL%E5%9F%BA%E7%A1%80) - [MySQL高级](https://gitee.com/duanchaojie/java-code/tree/master/5%E3%80%81MySQL%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AC%94%E8%AE%B0/MySQL%E9%AB%98%E7%BA%A7) Java框架[代码](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/code)和[笔记](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0) - [Spring](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/spring) - [SpringMvc](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/springmvc) - [MybatisPlus](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/MybatisPlus) - [SpringDataJpa](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/SpringDataJpa) - [SpringDataElasticsearch](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/SpringDataElasticsearch) - [RabbiteMQ](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/rabbitmq) - [SpringBoot](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/Springboot) - [SpringCloud](https://gitee.com/duanchaojie/java-code/tree/master/7%E3%80%81Java%E6%A1%86%E6%9E%B6%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/SpringCloud) - ....... [Java项目代码和笔记](https://gitee.com/duanchaojie/java-code/tree/master/8%E3%80%81Java%E9%A1%B9%E7%9B%AE%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0) - [简维商城](https://gitee.com/duanchaojie/java-code/tree/master/8%E3%80%81Java%E9%A1%B9%E7%9B%AE%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E7%AE%80%E7%BB%B4%E5%95%86%E5%9F%8E) - [品优购商城](https://gitee.com/duanchaojie/java-code/tree/master/8%E3%80%81Java%E9%A1%B9%E7%9B%AE%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E5%93%81%E4%BC%98%E8%B4%AD%E5%95%86%E5%9F%8E) - [乐优商城](https://gitee.com/duanchaojie/java-code/tree/master/8%E3%80%81Java%E9%A1%B9%E7%9B%AE%E4%BB%A3%E7%A0%81%E5%92%8C%E7%AC%94%E8%AE%B0/%E4%B9%90%E4%BC%98%E5%95%86%E5%9F%8E/%E7%AC%94%E8%AE%B0) - [谷粒学院](https://gitee.com/duanchaojie/guli-school.git) [大数据技术之Hadoop生态圈](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88) - [Hadoop基础](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/hadoop%E7%AC%94%E8%AE%B0) - [HDFS](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/HDFS) - [MapReduce](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/MapReduce) - [Yarn](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/Yarn) - [hadoop企业调优](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/hadoop%E4%BC%81%E4%B8%9A%E8%B0%83%E4%BC%98) - [ZooKeeper](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/ZooKeeper) - [Hive](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/Hive) - [Flume](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/Flume) - [Kafka](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/kafka) - [HBase](https://gitee.com/duanchaojie/java-code/tree/master/9%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E4%B9%8BHadoop%E7%94%9F%E6%80%81%E5%9C%88/Hbase) 大数据技术之Spark生态圈 - Scala[代码](https://gitee.com/duanchaojie/scala/tree/master/scala)和[笔记](https://gitee.com/duanchaojie/scala/tree/master/scala-note) - Spark[代码](https://gitee.com/duanchaojie/scala/tree/master/spark-study)和[笔记](https://gitee.com/duanchaojie/scala/tree/master/spark-note) # 安装教程 ~~~~shell git clone https://gitee.com/duanchaojie/java-code.git ~~~~ # 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request # Java学习路线 ![](https://oss-blogs.oss-cn-hangzhou.aliyuncs.com/blogs/JavaSE/Java%E8%B7%AF%E7%BA%BF.PNG) # ☆