大部分来源于网络

《零散知识点总结1》
该文章涉及:Dubbo、HTTP和HTTPS、Mybatis、Hibernate、 Zookeeper、Kafka、Elasticsearch、Redis

《零散知识点总结2》
该文章涉及:MySQL、Java并发编程、Java IO 和 NIO、JUnit单元测试

《零散知识点总结3》
该文章涉及 :Java Web、Spring、SpringMVC、Springboot、Springcloud、微服务

《零散知识点总结4》
该文章涉及:JVM和GC、Linux、Git、RabbitMQ

《零散知识点总结5》
该文章涉及:多线程、反射、对象拷贝、异常、容器

零散知识点总结4

  • JVM和GC
    • JVM 由哪些部分组成?
      • 说一下 JVM 运行时数据区?
      • 说一下堆栈的区别?(线性中堆和栈的区别)
      • 类加载过程
      • Java的引用
    • GC
      • 垃圾(GC)收集算法
    • GC的执行机制
      • JVM 有哪些垃圾回收器?
    • Java常见的内存泄漏
    • JVM调优命令有哪些?常见调优工具有哪些?
    • 你知道哪些JVM性能调优参数?(简单版回答)
    • 什么是双亲委派模型?
    • 说一下类装载的执行过程?
    • 怎么判断对象是否可以被回收?
    • Java 中都有哪些引用类型?
    • 说一下 JVM 有哪些垃圾回收算法?
    • 说一下 JVM 有哪些垃圾回收器?
    • 详细介绍一下 CMS 垃圾回收器?
    • 新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?
    • 简述分代垃圾回收器是怎么工作的?
    • 说一下 JVM 调优的工具?
    • 常用的 JVM 调优的参数都有哪些?
    • Java中实现多线程有几种方法?
    • 怎么获取 Java 程序使用的内存?堆使用的百分比?
    • Date、Time 及 Calendar
    • 在Java中如何格式化一个日期?(格式:ddMMyyyy)
    • Java 中,怎么在格式化的日期中显示时区?
    • Java 中 java.util.Date 与 java.sql.Date 有什么区别?
  • Linux
    • Linux 中进程有哪几种状态?在 ps 显示出来的信息中,分别用什么符号表示的?
    • 怎么查看系统支持的所有信号?
    • 查看各类环境变量用什么命令?
    • 通过什么命令指定命令提示符?
    • awk 详解
    • Linux命令及目录结构
    • Linux基本属性
    • 多种查看文件方式学习
    • Vim编辑器的使用
    • Linux账号管理学习
  • Git
    • Git基本理论(核心)
    • git入门——简易的命令行
    • 配置SSH公钥
    • git分支
    • Git文件操作
      • 忽略文件
  • RabbitMQ
    • RabbitMQ 的使用场景有哪些?有哪些重要的组件?节点作用是什么?有哪些重要的角色?
    • RabbitMQ 消息的处理问题
    • Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别?
    • RabbitMQ 的集群
    • MQ 的缺点
    • RabbitMQ 有几种广播类型?
    • RabbitMQ 集群有什么用?
    • RabbitMQ 节点的类型有哪些?
    • RabbitMQ 集群搭建需要注意哪些问题?
    • RabbitMQ 每个节点是其他节点的完整拷贝吗?为什么?
    • RabbitMQ 集群中唯一一个磁盘节点崩溃了会发生什么情况?
    • RabbitMQ 对集群节点停止顺序有要求吗?
    • redis和MQ如何平滑的扩容与缩容?
    • MQ的消息生产比消费速度快得多,有什么解决方案吗?

JVM和GC

JVM的三大子系统:类装载子系统【类加载器】:用于加载.class文件,但并不是在开始运行时加载所有类,而是当程序需要某个类时,才会加载。bootstrap加载器其他加载器执行引擎子系统:由虚拟机加载的类,被加载到Java虚拟机内存中之后,虚拟机会读取并执行它里面存在的字节码指令。虚拟机中执行字节码指令的部分叫做执行引擎。就像一个人,不是把饭吃下去就完事了,还要进行消化,执行引擎就相当于人的肠胃系统。在执行的过程中还会把各个class文件动态的连接起来。垃圾收集(GC):Java虚拟机会进行自动内存管理。具体说来就是自动释放没有用的对象,而不需要程序员编写代码来释放分配的内存。这部分工作由垃圾收集子系统负责。JVM2大组件:运行时数据区组件本地接口组件

JVM( Java Virtual Machine):Java虚拟机 JVM
GC(Garbage Collection):虚拟机垃圾处理机制 GC

什么是 JVM ?
JVM,即 Java Virtual Machine,Java 虚拟机。它通过模拟一个计算机来达到一个计算机所具有的的计算功能。JVM 能够跨计算机体系结构来执行 Java 字节码,主要是由于 JVM 屏蔽了与各个计算机平台相关的软件或者硬件之间的差异,使得与平台相关的耦合统一由 JVM 提供者来实现

JRE、JDK、JVM 及 JIT

  • JDK 代表 Java 开发工具(Java development kit),是 Java 程序的开发工具,如 Java编译器,它也包含 JRE。
    玩过Java的小伙伴应该都用过java -jar,javac等命令吧,如果只有jvm,jre,我们代码是写完了,但是怎么编译呢?或者代码出了问题怎么调试呢?这些都是JDK提供的,所以,jdk其实就是给我们提供了一些工具,一些命令,让我们完成编译代码,调试代码,反编译代码等操作。

  • JRE 代表 Java 运行时(Java run-time),是运行 Java 引用所必须的。
    JRE除了包含JVM之外,还提供了很多的类库,也就说我们说的jar包(比如:读取和操作文件,连接网络,IO等等),这些东西都是JRE提供的基础类库。JVM标准加上实现了一大堆类库,就组成了Java的运行时环境,也就是我们常说的JRE

  • JVM 代表 Java 虚拟机(Java virtual machine),它的责任是运行 Java 应用。
    JVM具体可以理解成就是一个平台,一个虚拟机,可以把class翻译成机器识别的代码。但是需要注意,JVM不会自己生成代码,需要大家编写代码,同时需要很多依赖库,这个就需要用到JRE

  • JIT 代表即时编译(Just In Time compilation),当代码执行的次数超过一定的阈值时,会将 Java 字节码转换为本地代码。如,主要的热点代码会被准换为本地代码,这样有利大幅度提高 Java 应用的性能。


一个Java程序运行,首先要经过 javac 编译器编译成.class字节码文件,.class文件是给JVM进行识别的,JVM将.class文件加载到方法区,执行引擎会执行这些字节码,执行时,会翻译成操作系统相关的函数(将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。)。

过程如下:Java文件->编译器->字节码->JVM->机器码

JVM 由哪些部分组成?

JVM 的结构基本上由 4 部分组成:类加载器、执行引擎、运行时数据区又称内存区、本地库接口
运行时数据区包括:虚拟机栈,本地方法栈,程序计数器、堆和方法区

说一下 JVM 运行时数据区?

不同虚拟机的运行时数据区可能略微有所不同,但都会遵从 Java 虚拟机规范, Java 虚拟机规范规定的区域分为以下 5 个部分:

  • Java 虚拟机栈(Java Virtual Machine Stacks):用于存储局部变量表、操作数栈、动态链接、方法出口等信息;
  • 本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;
  • 程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;
  • Java 堆(Java Heap):Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;
  • 方法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。

说一下堆栈的区别?(线性中堆和栈的区别)

特点
1、堆是存储单位,代表着数据,可被多个栈共享(包括成员中基本数据类型、引用和引用对象),所在区域不连续,会有碎片 ;2、堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中;3、堆内存是所有线程共有的;4、堆空间不足:java.lang.OutOfMemoryError;5、堆占用的内存空间大
1、栈是运行时单位,代表着逻辑,内含基本数据类型和堆中对象引用,所在区域连续,没有碎片;2、栈内存用来存储局部变量和方法调用;3、栈内存是线程私有的;4、栈空间不足:java.lang.StackOverFlowError;5、栈的空间大小远远小于堆的

小结:

  • 功能方面:堆是用来存放对象的,栈是用来执行程序的。
  • 共享性:堆是线程共享的,栈是线程私有的。
  • 空间大小:堆大小远远大于栈。

Java 中堆和栈的区别

JVM 中堆和栈属于不同的内存区域,使用目的也不同。
栈常用于保存方法帧和局部变量,而对象总是在堆上分配。
栈通常都比堆小,也不会在多个线程之间共享,而堆被整个 JVM 的所有线程共享。

队列和栈是什么?有什么区别?

队列和栈都是被用来预存储数据的。
队列允许先进先出检索元素,但也有例外的情况,Deque 接口允许从两端检索元素。
栈和队列很相似,但它运行对元素进行后进先出进行检索。

组件的作用: 首先通过类加载器(ClassLoader)会把 Java 代码转换成字节码,运行时数据区(Runtime Data Area)再把字节码加载到内存中,而字节码文件只是 JVM 的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。

类加载过程

  • 加载(装载):获得类的二进制流,存入方法区运行时数据,生成Java.lang.Class作为各种数据访问接口

  • 验证:class甚至可以由自己创建16进制的文件获得,但要满足一定条件,如文件格式:开头几个字是CA FE BA BY,后面是主版本号次版本号,常量池等等;元数据验证:类是否有父类,是否继承了final类,抽象类的实现类是否实现了所有方法;字节码验证:类型转换;符号引用验证;

  • 准备:为类变量分配内存并设置类变量初始值,都在方法区内执行。只会分配类变量(static修饰),实例变量是在对象实例化时一起分配在堆中。Private static int value=123 存的是初始值0,value=123是在初始化阶段执行的。Private static final int value=123 ,因为是final修饰,存的是123。

  • 解析:将常量池中的符号引用替换为直接引用的过程

  • 初始化:类构造器执行的方法,即初始化静态变量和静态代码块(准备阶段是设置类变量初始值)。方法仅在类有类变量赋值或者静态代码块时才执行,对于类会默认先执行父类中的方法,接口里的变量默认是static final类型,所以不会执行父类的。如果多线程同时去初始化一个类,只会有一个执行,其他阻塞,且同一个classLoader只会初始化一次同一个类。

  • 使用

  • 卸载

Java 虚拟机(JVM)是如何判定两个 Java 类是相同的?

判断相同要看类的全名是否相同,还要看加载此,类的类加载器是否一样,两同即是相同
注意:不同的两个类互相赋值会报ClassCastException异常

64 位 JVM 中,int 的长度是多数?

Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位。意思就是说,在 32 位 和 64 位 的 Java 虚拟机中,int 类型的长度是相同的。

Serial 与 Parallel GC 之间的不同之处?

Serial 与 Parallel 在 GC 执行的时候都会引起 stop-the-world。它们之间主要不同 serial 收集器是默认的复制收集器,执行 GC 的时候只有一个线程,而parallel 收集器使用多个 GC 线程来执行。

怎样通过 Java 程序来判断 JVM 是 32 位 还是 64位?

你可以检查某些系统属性如 sun.arch.data.modelos.arch 来获取该信息

32 位 JVM 和 64 位 JVM 的最大堆内存分别是多数?

理论上说上 32 位的 JVM 堆内存可以到达 2的32次方【2^32即 4GB】,但实际上会比这个小很多。
不同操作系统之间不同,如 Windows 系统大约 1.5 GB,Solaris 大约3GB。64 位 JVM 允许指定最大的堆内存,理论上可以达到2的64次方【 2^64】,这是一个非常大的数字,实际上你可以指定堆内存大小到 100GB。甚至有的 JVM,如 Azul,堆内存到 1000G 都是可能的。

Java的引用

可以看出分析对象是否存活,都与引用有关。在JDK1.2之后,Java对引用的概念进行了扩充,将引用分为 强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)

  • 强引用
    强引用即为原来意义上的引用,只要强引用存在,被引用的对象就不会被回收

  • 软引用
    SoftReference类表示软引用,对于被软引用关联的对象,在系统将要发生内存溢出时,会把这些对象列入回收范围后,进行二次回收(软引用虽然不能阻止被回收,但是可以延迟到 JVM 内存不足的时候再被回收)

  • 弱引用
    WeakReference类表示弱引用,对于被弱引用关联的对象,只能生存到下一次垃圾回收发生之前(弱引用一旦失去最后一个强引用,就会被 GC 回收)

  • 虚引用
    PhantomReference类表示虚引用,虚引用不对关联的对象的生存时间构成影响,也无法取得对象实例,它唯一的作用是在对象被GC回收是收到一条系统通知

GC

垃圾(GC)收集算法

GC最基础的算法有三种: 标记 -清除算法、复制算法、标记-压缩算法,我们常用的垃圾回收器一般都采用分代收集算法

  • 分代收集算法,“分代收集”(Generational Collection)算法,把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。

  • 标记 -清除算法,“标记-清除”(Mark-Sweep)算法,如它的名字一样,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。

  • 复制算法,“复制”(Copying)的收集算法,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

  • 标记-压缩算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存

GC的执行机制

由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Scavenge GC和Full GC。

  • Minor GC
    一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Minor GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

  • Full GC
    对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个堆进行回收,所以比Minor GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:
     1.年老代(Tenured)被写满
     2.持久代(Perm)被写满
     3.System.gc()被显示调用
     4.上一次GC之后Heap的各域分配策略动态变化

Minor GC与Full GC分别在什么时候发生?
新生代内存不够用时候发生MGC也叫YGC,JVM内存不够的时候发生FGC

你能保证 GC 执行吗?

不能,虽然你可以调用 System.gc() 或者 Runtime.gc(),但是没有办法保证 GC的执行

JVM 有哪些垃圾回收器?

如果说垃圾收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。下图展示了7种作用于不同分代的收集器,不同收集器之间的连线表示它们可以搭配使用。

新生代收集器:Serial、 ParNew 、 Parallel Scavenge
老年代收集器: CMS 、Serial Old、Parallel Old
整堆收集器: G1 , ZGC (因为不涉年代不在图中)

Java常见的内存泄漏

  1. 数据库连接,网络连接,IO连接等没有显示调用close关闭,会导致内存泄露
  2. 监听器的使用,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露

JVM调优命令有哪些?常见调优工具有哪些?

Sun JDK监控和故障处理命令有jps jstat jmap jhat jstack jinfo

jps,JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程。
jstat,JVM statistics Monitoring是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。
jmap,JVM Memory Map命令用于生成heap dump文件
jhat,JVM Heap Analysis Tool命令是与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看
jstack,用于生成java虚拟机当前时刻的线程快照。
jinfo,JVM Configuration info 这个命令作用是实时查看和调整虚拟机运行参数。

常见调优工具

常用调优工具分为两类:jdk自带监控工具:jconsole:Java Monitoring and Management Console是从java5开始,在JDK中自带的java监控和管理控制台,用于对JVM中内存,线程和类等的监控jvisualvm:jdk自带全能工具,可以分析内存快照、线程快照;监控内存变化、GC变化等第三方工具:MAT(Memory Analyzer Tool):一个基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗GChisto:一款专业分析gc日志的工具

你知道哪些JVM性能调优参数?(简单版回答)

设定堆内存大小-Xmx:堆内存最大限制。
设定新生代大小。 新生代不宜太小,否则会有大量对象涌入老年代-XX:NewSize:新生代大小-XX:NewRatio 新生代和老生代占比-XX:SurvivorRatio:伊甸园空间和幸存者空间的占比
设定垃圾回收器 年轻代用 -XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC

详细版回答
「堆栈内存相关」

-Xms 设置初始堆的大小
-Xmx 设置最大堆的大小
-Xmn 设置年轻代大小,相当于同时配置-XX:NewSize和-XX:MaxNewSize为一样的值
-Xss 每个线程的堆栈大小
-XX:NewSize 设置年轻代大小(for 1.3/1.4)
-XX:MaxNewSize 年轻代最大值(for 1.3/1.4)
-XX:NewRatio 年轻代与年老代的比值(除去持久代)
-XX:SurvivorRatio Eden区与Survivor区的的比值
-XX:PretenureSizeThreshold 当创建的对象超过指定大小时,直接把对象分配在老年代。
-XX:MaxTenuringThreshold设定对象在Survivor复制的最大年龄阈值,超过阈值转移到
老年代

「垃圾收集器相关」

-XX:+UseParallelGC:选择垃圾收集器为并行收集器。
-XX:ParallelGCThreads=20:配置并行收集器的线程数
-XX:+UseConcMarkSweepGC:设置年老代为并发收集。
-XX:CMSFullGCsBeforeCompaction=5 由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行5次GC以后对内存空间进行压缩、整理。
-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,但是可以消除碎片

「辅助信息相关」

-XX:+PrintGCDetails 打印GC详细信息
-XX:+HeapDumpOnOutOfMemoryError让JVM在发生内存溢出的时候自动生成内存快照,排查问题用
-XX:+DisableExplicitGC禁止系统System.gc(),防止手动误触发FGC造成问题.
-XX:+PrintTLAB 查看TLAB空间的使用情况

类似-Xms、-Xmn这些参数的含义

堆内存分配

  • JVM初始分配的内存由-Xms指定,默认是物理内存的1/64
  • JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4
    默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;
    空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。

因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

非堆内存分配

  • JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
  • 由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
  • -Xmn2G:设置年轻代大小为2G。
  • -XX:SurvivorRatio,设置年轻代中Eden区与Survivor区的比值。

什么是双亲委派模型?

在介绍双亲委派模型之前先说下类加载器。对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立在 JVM 中的唯一性,每一个类加载器,都有一个独立的类名称空间。类加载器就是根据指定全限定名称将 class 文件加载到 JVM 内存,然后再转化为 class 对象。

类加载器分类:

  • 启动类加载器(Bootstrap ClassLoader),是虚拟机自身的一部分,用来加载Java_HOME/lib/目录中的,或者被 -Xbootclasspath 参数所指定的路径中并且被虚拟机识别的类库;
  • 其他类加载器:
  • 扩展类加载器(Extension ClassLoader):负责加载<Java_HOME>\lib\ext目录或Java. ext. dirs系统变量指定的路径中的所有类库;
    应用程序类加载器(Application ClassLoader)。负责加载用户类路径(classpath)上的指定类库,我们可以直接使用这个类加载器。一般情况,如果我们没有自定义类加载器默认就是用这个加载器。

双亲委派模型:如果一个类加载器收到了类加载的请求,它首先不会自己去加载这个类,而是把这个请求委派给父类加载器去完成,每一层的类加载器都是如此,这样所有的加载请求都会被传送到顶层的启动类加载器中,只有当父加载无法完成加载请求(它的搜索范围中没找到所需的类)时,子加载器才会尝试去加载类。

说一下类装载的执行过程?

类装载分为以下 5 个步骤:

  • 加载:根据查找路径找到相应的 class 文件然后导入;
  • 检查:检查加载的 class 文件的正确性;
  • 准备:给类中的静态变量分配内存空间;
  • 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;
  • 初始化:对静态变量和静态代码块执行初始化工作。

怎么判断对象是否可以被回收?

一般有两种方法来判断:

  • 引用计数器:为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题;

  • 可达性分析:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。

Java 中都有哪些引用类型?

  • 强引用:发生 gc 的时候不会被回收。
  • 软引用:有用但不是必须的对象,在发生内存溢出之前会被回收。
  • 弱引用:有用但不是必须的对象,在下一次GC时会被回收。
  • 虚引用(幽灵引用/幻影引用):无法通过虚引用获得对象,用 PhantomReference 实现虚引用,虚引用的用途是在 gc 时返回一个通知。

说一下 JVM 有哪些垃圾回收算法?

  • 标记-清除算法:标记无用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片。
  • 标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。
  • 复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半。
  • 分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本采用复制算法,老年代采用标记整理算法。

说一下 JVM 有哪些垃圾回收器?

  • Serial:最早的单线程串行垃圾回收器。
  • Serial Old:Serial 垃圾回收器的老年版本,同样也是单线程的,可以作为 CMS 垃圾回收器的备选预案。
  • ParNew:是 Serial 的多线程版本。
  • Parallel 和 ParNew 收集器类似是多线程的,但 Parallel 是吞吐量优先的收集器,可以牺牲等待时间换取系统的吞吐量。
  • Parallel Old 是 Parallel 老生代版本,Parallel 使用的是复制的内存回收算法,Parallel Old 使用的是标记-整理的内存回收算法。
    –CMS:一种以获得最短停顿时间为目标的收集器,非常适用 B/S 系统。
  • G1:一种兼顾吞吐量和停顿时间的 GC 实现,是 JDK 9 以后的默认 GC 选项。

详细介绍一下 CMS 垃圾回收器?

CMS 是英文 Concurrent Mark-Sweep 的简称,是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上,这种垃圾回收器非常适合。在启动 JVM 的参数加上“-XX:+UseConcMarkSweepGC”来指定使用 CMS 垃圾回收器。

CMS 使用的是标记-清除的算法实现的,所以在 gc 的时候回产生大量的内存碎片,当剩余内存不能满足程序运行要求时,系统将会出现 Concurrent Mode Failure,临时 CMS 会采用 Serial Old 回收器进行垃圾清除,此时的性能将会被降低。

新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

  • 新生代回收器:Serial、ParNew、Parallel Scavenge
  • 老年代回收器:Serial Old、Parallel Old、CMS
  • 整堆回收器:G1

新生代垃圾回收器一般采用的是复制算法,复制算法的优点是效率高,缺点是内存利用率低;老年代回收器一般采用的是标记-整理的算法进行垃圾回收。

简述分代垃圾回收器是怎么工作的?

分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3。

新生代使用的是复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,它的执行流程如下:

  • 把 Eden + From Survivor 存活的对象放入 To Survivor 区;
  • 清空 Eden 和 From Survivor 分区;
  • From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor。

每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。大对象也会直接进入老生代。

老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记整理的执行算法。以上这些循环往复就构成了整个分代垃圾回收的整体执行流程。

说一下 JVM 调优的工具?

JDK 自带了很多监控工具,都位于 JDK 的 bin 目录下,其中最常用的是 jconsole 和 jvisualvm 这两款视图监控工具。

  • jconsole:用于对 JVM 中的内存、线程和类等进行监控;
  • jvisualvm:JDK 自带的全能分析工具,可以分析:内存快照、线程快照、程序死锁、监控内存的变化、gc 变化等。

常用的 JVM 调优的参数都有哪些?

  • -Xms2g:初始化推大小为 2g;
  • -Xmx2g:堆最大内存为 2g;
  • -XX:NewRatio=4:设置年轻的和老年代的内存比例为 1:4;
  • -XX:SurvivorRatio=8:设置新生代 Eden 和 Survivor 比例为 8:2;
  • –XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合;
  • -XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器组合;
  • -XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组合;
  • -XX:+PrintGC:开启打印 gc 信息;
  • -XX:+PrintGCDetails:打印 gc 详细信息。

Java中实现多线程有几种方法?

  1. 继承Thread 类
  2. 实现Runnable类
  3. 实现Callable类(JDK1.5开始)
  4. 线程池方式创建

怎么获取 Java 程序使用的内存?堆使用的百分比?

可以通过 java.lang.Runtime 类中与内存相关方法来获取剩余的内存,总内存及最大堆内存。通过这些方法你也可以获取到堆使用的百分比及堆内存的剩余空间。
Runtime.freeMemory() 方法返回剩余空间的字节数,
Runtime.totalMemory()方法总内存的字节数,
Runtime.maxMemory() 返回最大内存的字节数。

Date、Time 及 Calendar

在多线程环境下,SimpleDateFormat 是线程安全的吗?

不是,非常不幸,DateFormat 的所有实现,包括 SimpleDateFormat 都不是线程安全的,因此你不应该在多线程序中使用,除非是在对外线程安全的环境中使用,如 将 SimpleDateFormat 限制在 ThreadLocal 中。如果你不这么做,在解析或者格式化日期的时候,可能会获取到一个不正确的结果。因此,从日期、时间处理的所有实践来说,我强力推荐 joda-time 库。

在Java中如何格式化一个日期?(格式:ddMMyyyy)

Java 中,可以使用 SimpleDateFormat 类或者 joda-time 库来格式日期。
DateFormat 类允许你使用多种流行的格式来格式化日期。参见答案中的示例代码,代码中演示了将日期格式化成不同的格式,如 dd-MM-yyyy 或 ddMMyyyy。

举例子:

Date datenow = new Date();
SimpleDateFormat ft = new SimpleDateFormat("yyyy.MM.dd hh:mm:ss"); System.out.println(ft.format(datenow));/*注意:
1、 调用 SimpleDateFormat 对象的 parse() 方法时可能会出现转换异常,即 ParseException ,因此需要进行异常处理
2、 使用 Date 类时需要导入 java.util 包,使用 SimpleDateFormat 时需要导入 java.text
*/
public static void main(String[] args){ // 使用format()方法将日期转换为指定格式的文本 SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm"); SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 创建Date对象,表示当前时间 Date now = new Date(); // 调用format()方法,将日期转换为字符串并输出 System.out.println(sdf1.format(now));//2019年02月11日 21时50分48秒       System.out.println(sdf2.format(now));//2019/02/11 21:50 System.out.println(sdf3.format(now));//2019-02-11 21:50:48 // 使用parse()方法将文本转换为日期 String d = "2019-2-11 21:50:36"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 调用parse()方法,将字符串转换为日期 try { //注意一定要和指定的格式匹配 Date date =sdf.parse(d); System.out.println(date);//Mon Feb 11 21:50:36 CST 2019 }catch(ParseException e){ e.printStackTrace(); }
}

Java 中,怎么在格式化的日期中显示时区?

其实在格式化的加上Z,表示的就是时区

String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z",
Locale.ENGLISH).format(new Date());//2022-3-9 12:40:40.203 +0800

Java 中 java.util.Date 与 java.sql.Date 有什么区别?

  • java.util.Date包含日期和时间,(在除了SQL语句的情况下面使用,表示时间的类,我们通常格式化或者得到当前时间都是用他)
  • java.sql.Date只包含日期信息,而没有具体的时间信息。如果你想把时间信息存储在数据库 里,可以考虑使用Timestamp或者DateTime字段。(是针对SQL语句使用的,在读写数据库的时候用他,因为PreparedStamentsetDate()的第2参数和ResultSet的getDate()方法的第2个参数都是java.sql.Date
    转换是
    java.sql.Date date=new Java.sql.Date();
    java.util.Date d=new java.util.Date (date.getTime());
    反过来是一样的java.sql.DategetTime方法返回毫秒数,自然就可以直接构建
    java.util.Date d = new java.util.Date(sqlDate.getTime());

继承关系:java.lang.Object --》 java.util.Date --》 java.sql.Date
具体的转换关系就是java.util.Date d=new java.util.Date (new Java.sql.Date());

SimpleDateFormat f=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");java.util.Date utilDate=new Date();      java.sql.Date sqlDate=new java.sql.Date(utilDate.getTime());        java.sql.Time sTime=new java.sql.Time(utilDate.getTime());   java.sql.Timestamp stp=new java.sql.Timestamp(utilDate.getTime());System.out.println(utilDate.getYear());//这里所有时间日期都可以被SimpleDateFormat格式化format()
f.format(stp);f.format(sTime);f.format(sqlDate);f.format(utilDate)
java.sql.Date sqlDate=java.sql.Date.valueOf("2005-12-12");
utilDate=new java.util.Date(sqlDate.getTime());
//===另类取得年月日的方法:===
import java.text.SimpleDateFormat;
import java.util.*;
java.util.Date date = new java.util.Date();//如果希望得到YYYYMMDD的格式
SimpleDateFormat sy1=new SimpleDateFormat("yyyyMMDD");
String dateFormat=sy1.format(date);//如果希望分开得到年,月,日
SimpleDateFormat sy=new SimpleDateFormat("yyyy");
SimpleDateFormat sm=new SimpleDateFormat("MM");
SimpleDateFormat sd=new SimpleDateFormat("dd");
String syear=sy.format(date);
String smon=sm.format(date);
String sday=sd.format(date);

转载于博客:https://www.cnblogs.com/IamThat/p/3264234.html

Java 中,如何计算两个日期之间的差距

答案参考:https://www.cnblogs.com/rinack/p/6798433.html
Java 中,如何将字符串 YYYYMMDD 转换为日期?
举例子:20220309转换为2022年03月09日

import java.util.*;
import java.text.*;
import java.io.*;class StrToDate{public static void main(String[] args){String dateString = "20220309";try {Date date=new SimpleDateFormat("yyyyMMdd").parse(dateString);/*DateFormat.getInstance();  // 得到日期时间都使用SHORT风格的日期时间格式化器DateFormat.getDateInstance();  // 得到日期格式化器,使用默认语言环境和默认风格DateFormat.getDateTimeInstance(); // 得到日期时间格式化器,使用默认语言环境和默认风格*/System.out.println(DateFormat.getDateInstance().format(date));//输出的结果为2022-03-09System.out.println(new SimpleDateFormat("yyyy/MM/dd").format(date));//输出的结果为2022/03/09//SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");System.out.println(new SimpleDateFormat("yyyy年MM月dd日").format(date));//输出的结果为2022年03月09日} catch (Exception ex) {System.out.println(ex.getMessage());}}
}

Linux

《DOS、Linux、Git 的常用命令》
《Linux的基础学习(开发)》
《Linux命令》

为什么要学习Linux

Linux简介与应用领域




绝对路径用什么符号表示?当前目录、上层目录用什么表示?主目录用什么表示? 切换目录用什么命令?

绝对路径:/etc/init.d
当前目录: ./
上层目录:../
主目录用:~/
切换目录:cd

怎么查看当前进程?怎么执行退出?怎么查看当前路径?

查看当前进程: ps
执行退出: exit
查看当前路径: pwd

怎么清屏?怎么退出当前命令?怎么执行睡眠?怎么查看当前用户 id?查看指定帮助用什么命令?

清屏: clear
退出当前命令: ctrl+c 彻底退出
执行睡眠 : ctrl+z 挂起当前进程  fg 恢复后台
查看当前用户 id: ”id“:查看显示目前登陆账户的 uid 和 gid 及所属分组及用户名
查看指定帮助: 如 man adduser 这个很全 而且有例子; adduser --help 这个告诉你一些常用参数; info adduesr;

Ls 命令执行什么功能? 可以带哪些参数,有什么区别?

ls 执行的功能: 列出指定目录中的目录,以及文件
哪些参数以及区别: a 所有文件 l 详细信息,包括大小字节数,可读可写可执行的权限等

命令:ls [-al]ls                查看当前目录下的所有目录和文件
ls -a            查看当前目录下的所有目录和文件(包括隐藏的文件)
ls -l 或 ll       列表查看当前目录下的所有目录和文件(列表查看,显示更多信息)
ls /dir            查看指定目录下的所有目录和文件   如:ls /usr

建立软链接(快捷方式),以及硬链接的命令。

软链接: ln -s slink source
硬链接: ln link source

举个例子:

目录创建用什么命令?创建文件用什么命令?复制文件用什么命令?

创建目录: mkdir
创建文件:典型的如 touch,vi 也可以创建文件(其实只要向一个不存在的文件输出,都会创建文件)
复制文件: cp

文件权限修改用什么命令?格式是怎么样的?

文件权限修改: chmod
格式如下:

chmodu +x file 给 file 的属主增加执行权限
chmod 751 file 给 file 的属主分配读、写、执行(7)的权限,给 file 的所在组分配读、执行(5)的权限,给其他用户分配执行(1)的权限
chmodu=rwx,g=rx,o=xfile 上例的另一种形式 chmod =r file 为所有用户分配读权限
chmod 444 file 同上例 chmod a-wx,a+r file
同上例$ chmod -R u+r directory 递归地给 directory 目录下所有文件和子目录的属主分配读的权限

查看文件内容有哪些命令可以使用?

vi 文件名 #编辑方式查看,可修改
cat 文件名 #显示全部文件内容
more 文件名 #分页显示文件内容
less 文件名 #与 more 相似,更好的是可以往前翻页
tail 文件名 #仅查看尾部,还可以指定行数
head 文件名 #仅查看头部,还可以指定行数

随意写文件命令?怎么向屏幕输出带空格的字符串,比如”hello world”?

写文件命令:vi
向屏幕输出带空格的字符串:echo hello world

终端是哪个文件夹下的哪个文件?黑洞文件是哪个文件夹下的哪个命令?

终端 /dev/tty
黑洞文件 /dev/null

移动文件用哪个命令?改名用哪个命令?

mv

复制文件用哪个命令?如果需要连同文件夹一块复制呢?如果需要有提示功能呢?

cp cp -r ????

删除文件用哪个命令?如果需要连目录及目录下文件一块删除呢?删除空文件夹用什么命令?

rm
rm -r
rm dir

Linux 下命令有哪几种可使用的通配符?分别代表什么含义?

“?”可替代单个字符。
“*”可替代任意多个字符。
方括号“[charset]”可替代 charset 集中的任何单个字符,如[a-z],[abABC]

用什么命令对一个文件的内容进行统计?(行号、单词数、字节数)

wc 命令 - c 统计字节数 - l 统计行数 - w 统计字数。

Grep 命令有什么用? 如何忽略大小写? 如何查找不含该串的行?

是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来

grep [stringSTRING] filename grep [^string] filename

Linux 中进程有哪几种状态?在 ps 显示出来的信息中,分别用什么符号表示的?

Linux 中进程有哪几种状态:

1、不可中断状态:进程处于睡眠状态,但是此刻进程是不可中断的。不可中断,指进程不响应异步信号。
2、暂停状态/跟踪状态:向进程发送一个 SIGSTOP 信号,它就会因响应该信号 而进入 TASK_STOPPED 状态;当进程正在被跟踪时,它处于 TASK_TRACED 这个特殊的状态。正被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。
3、就绪状态:在 run_queue 队列里的状态
4、运行状态:在 run_queue 队列里的状态
5、可中断睡眠状态:处于这个状态的进程因为等待某某事件的发生(比如等待socket 连接、等待信号量),而被挂起
6、zombie 状态(僵尸):父亲没有通过 wait 系列的系统调用会顺便将子进程的尸体(task_struct)也释放掉
7、退出状态  D 不可中断 Uninterruptible(usually IO)R 正在运行,或在队列中的进程S 处于休眠状态T 停止或被追踪Z 僵尸进程W 进入内存交换(从内核 2.6 开始无效)X 死掉的进程

怎么使一个命令在后台运行?

一般都是使用 & 在命令结尾来让程序自动运行。(命令后可以不追加空格)

利用 ps 怎么显示所有的进程? 怎么利用 ps 查看指定进程的信息?

ps -ef (system v 输出)
ps -aux bsd 格式输出
ps -ef | grep pid

哪个命令专门用来查看后台任务?

job -l

把后台任务调到前台执行使用什么命令?把停下的后台任务在后台执行起来用什么命令?

把后台任务调到前台执行 fg
把停下的后台任务在后台执行起来 bg

终止进程用什么命令? 带什么参数?

kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>]
kill-9 pid

怎么查看系统支持的所有信号?

kill -l

搜索文件用什么命令? 格式是怎么样的?

find <指定目录> <指定条件> <指定动作>
where is 加参数与文件名
locate 只加文件名
find 直接搜索磁盘,较慢。
find / -name "string*"

查看当前谁在使用该主机用什么命令? 查找自己所在的终端信息用什么命令?

查找自己所在的终端信息:who am i
查看当前谁在使用该主机:who

使用什么命令查看用过的命令列表?

history

使用什么命令查看磁盘使用空间? 空闲空间呢?

df -hl

文件系统 容量 已用 可用 已用% 挂载点

Filesystem Size Used Avail Use% Mounted on /dev/hda2 45G 19G 24G 44% //dev/hda1 494M 19M 450M 4% /boot

使用什么命令查看网络是否连通?

netstat

使用什么命令查看 ip 地址及接口信息?

ifconfig

注意别混淆了
Linux用 ifconfig
window 用 ipconfig

查看各类环境变量用什么命令?

查看所有 env
查看某个,如 home: env $HOME

通过什么命令指定命令提示符?

  • \u:显示当前用户账号
  • \h:显示当前主机名
    第 447 页 共 485 页  \W:只显示当前路径最后一个目录
  • \w:显示当前绝对路径(当前用户目录会以~代替)
  • $PWD:显示当前全路径
  • :显示命令行’:显示命令行’:显示命令行’'或者’#'符号
  • #:下达的第几个命令
  • \d:代表日期,格式为 week day month date,例如:“MonAug1”
  • \t:显示时间为 24 小时格式,如:HH:MM:SS
  • \T:显示时间为 12 小时格式
  • \A:显示时间为 24 小时格式:HH:MM
  • \v:BASH 的版本信息 如 export PS1=’[\u@\h\w#]$‘

查找命令的可执行文件是去哪查找的? 怎么对其进行设置及添加?

where is [-bfmsu][-B <目录>...][-M <目录>...][-S <目录>...][文件...]

补充说明:where is 指令会在特定目录中查找符合条件的文件。这些文件的烈性
应属于原始代码,二进制文件,或是帮助文件。

  • -b 只查找二进制文件。
  • -B <目录> 只在设置的目录下查找二进制文件。 -f 不显示文件名前的路径名称。
  • -m 只查找说明文件。
  • -M <目录> 只在设置的目录下查找说明文件。-s 只查找原始代码文件。  -S <目录> 只在设置的目录下查找原始代码文件。 -u 查找不包含指定类型的文件。
    w -h ich 指令会在 PATH 变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果。
  • -n 指定文件名长度,指定的长度必须大于或等于所有文件中最长的文件名。
  • -p 与-n 参数相同,但此处的包括了文件的路径。 -w 指定输出时栏位的宽度。
  • -V 显示版本信息

通过什么命令查找执行命令?

which 只能查可执行文件
whereis 只能查二进制文件、说明文档,源文件等

怎么对命令进行取别名?

alias la='ls -a'

du 和 df 的定义,以及区别?

du 显示目录或文件的大小
df 显示每个<文件>所在的文件系统的信息,默认是显示所有文件系统。
(文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如 i 节点,磁盘
分布图,间接块,超级块等。这些数据对大多数用户级的程序来说是不可见的,
通常称为 Meta Data。)

du 命令是用户级的程序,它不考虑 Meta Data,而 df命令则查看文件系统的磁盘分配图并考虑 Meta Data。

df 命令获得真正的文件系统数据,而 du 命令只查看文件系统的部分情况。

awk 详解

awk '{pattern + action}' {filenames}
#cat /etc/passwd |awk -F ':' '{print 1"\t"7}' //-F 的意思是以':'分隔 root/bin/bash
daemon /bin/sh 搜索/etc/passwd 有 root 关键字的所有行
#awk -F: '/root/' /etc/passwd root:x:0:0:root:/root:/bin/bash

当你需要给命令绑定一个宏或者按键的时候,应该怎么做呢?

可以使用 bind 命令,bind 可以很方便地在 shell 中实现宏或按键的绑定。在进行按键绑定的时候,我们需要先获取到绑定按键对应的字符序列。比如获取 F12 的字符序列获取方法如下:先按下 Ctrl+V,然后按下 F12 .我们就可以得到 F12 的字符序列 ^[[24~。接着使用 bind 进行绑定。[root@localhost ~]# bind ‘”\e[24~":"date"'

注意:相同的按键在不同的终端或终端模拟器下可能会产生不同的字符序列。

【附】也可以使用 showkey -a 命令查看按键对应的字符序列。

如果一个 linux 新手想要知道当前系统支持的所有命令的列表,他需要怎么做?

使用命令 compgen -c,可以打印出所有支持的命令列表。

[root@localhost ~]$ compgen -c
l.
ll
ls
which
if
then
else
elif
fi
case
esac
for
select
while
until
do
done
…

如果你的助手想要打印出当前的目录栈,你会建议他怎么做?

使用 Linux 命令 dirs 可以将当前的目录栈打印出来。

[root@localhost ~]# dirs
/usr/share/X11

【附】:目录栈通过 pushd pop

你的系统目前有许多正在运行的任务,在不重启机器的条件下,有什么方法可以把所有正在运行的进程移除呢?

使用 linux 命令 ’disown -r ’可以将所有正在运行的进程移除。

bash shell 中的 hash 命令有什么作用?

linux 命令’hash’管理着一个内置的哈希表,记录了已执行过的命令的完整路径,用该命令可以打印出你所使用过的命令以及执行的次数。

[root@localhost ~]# hash
hits command
2 /bin/ls
2 /bin/su

哪一个 bash 内置命令能够进行数学运算。

bash shell 的内置命令 let 可以进行整型数的数学运算

#! /bin/bash
……
let c=a+b
……

怎样一页一页地查看一个大文件的内容呢?

通过管道将命令”cat file_name.txt” 和 ’more’ 连接在一起可以实现这个
需要

[root@localhost ~]# cat file_name.txt | more

数据字典属于哪一个用户的?

数据字典是属于’SYS’用户的,用户‘SYS’ 和 ’SYSEM’是由系统默认自动
创建的

怎样查看一个 linux 命令的概要与用法?假设你在/bin 目录中偶然看到一个你从没见过的的命令,怎样才能知道它的作用和用法呢?

使用命令 whatis 可以先出显示出这个命令的用法简要,
比如,你可以使用 whatis zcat 去查看‘zcat’的介绍以及使用简要。

[root@localhost ~]# whatis zcat
zcat [gzip] (1) – compress or expand files

使用哪一个命令可以查看自己文件系统的磁盘空间配额呢?

使用命令 repquota 能够显示出一个文件系统的配额信息
【附】只有 root 用户才能够查看其它用户的配额。

Linux命令及目录结构

推荐——《Linux常用命令》


Linux基本属性




多种查看文件方式学习


注意:less与more 命令的退出命令都是p(键盘按一下p键就可以退出命令)

cd /etc/sysconfig/

Vim编辑器的使用






Linux账号管理学习





查看:cat /etc/passwd
hqp:x:1001:1001::/home/hqp:/bin/bash  变为
hqp:x:1001:1001::/home/233:/bin/bash







Git

git安装教程
Git 官网
淘宝镜像下载git

Git基本理论(核心)

工作区域
Git本地有三个工作区域:工作目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)。如果再加上远程的git仓库(Remote Directory)就可以分为四个工作区域。文件在这四个区域之间的转换:


工作流程
1、 在工作目录中添加、修改文件;
2、 将需要进行版本管理的文件放入暂存区域;
3、 将暂存区域的文件提交到git仓库
因此,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)

git入门——简易的命令行

# 显示当前的Git配置
git config --list# 编辑Git配置文件
git config -e [--global]# 设置提交代码时的用户信息【Git 全局设置】
git config [--global] user.name "[name]"
git config [--global] user.email "[email address]"# 创建 git 仓库:
mkdir gitstudy
cd gitstudy
git init
touch README.md
git add README.md
git commit -m "first commit"git remote add origin https://gitee.com/asl_gitee/gitstudy.git
git push -u origin "master"
#已有仓库?
cd existing_git_repogit remote add origin https://gitee.com/asl_gitee/gitstudy.git
git push -u origin "master"

举个例子:

git config --global user.name "hh"
git config --global user.email "[20****4714@qq.com]"

配置SSH公钥

ssh-keygen -t rsa -C "email address"


举例子:

例如我保存在了C盘的这个目录C:\Users\HEQIUPING\.ssh

这时候就将密钥添加到gitee


输入命令:git clone git@gitee.com:asl_gitee/springcloud-config.git 将代码克隆下来

git分支

Git分支管理常用命令;
git branch              (列出)显示所有分支
git branch -r               列出所有远程分支
git branch b1           从当前分支创建一个叫b1的分支
git checkout b1         切换到b1分支
git checkout -b b1      新建一个b1分支,并切换到b1分支
git checkout master     切换到master主分支
git merge b1            合并指定分支b1到当前分支(把b1分支的代码合并到master上)
git branch -d b1        删除b1分支,不能在被删除分支上执行
git push -u origin dev1      提交分支到远程
git push origin --delete xxxxxx   * 删除远程分支
git branch -dr [remote/branch]   删除远程分支



Git文件操作

文件4种状态
版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。

  • Untracked:未跟踪,此文件在文件夹中,但并没有加入到git库,不参与版本控制,通过 git add状态变为Staged。===刚刚新建的文件

  • Unmodify:文件已经入库,未修改,即版本库中的文件快照内容与文件夹中完全一致。这种类型的文件有两种去处,如果他被修改,而变为Modified。如果使用git rm移出版本库,则成为Untracked文件

  • Modified:文件已修改,仅仅是修改,并没有进行其他的操作。这个文件也有两个去处,通过git add可进入暂存staged状态,使用git checkout则丢弃修改过,返回到unmodify状态,这个git checkout即从库中取出文件,覆盖当前修改

  • Staged:暂存状态。执行git commit则将修改同步到库中,这时库中的问价和本地文件又变为一致,文件为Unmodify状态。执行git reset HEAD filename 取消暂存,文件状态为Modified

忽略文件

有些时候我们不想把某些问价纳入版本控制中,比如数据库文件,临时文件,设计文件等

在目录下建立“.gitignore”文件,此文件有如下规则:

1、 忽略文件中的空行或以井号(#)开始的行将会被忽略
2、 可以使用Linux通配符。例如:星号(*)代表任意多个字符,问号(?)代表一个字符,方括号([asdfg])代表可选字符范围,大括号({string1,string2,……})代表可选的字符串等。
3、 如果名称的最前面有一个感叹号(!),表示例外规则,将不被忽略
4、 如果名称的最前面是一个路径分隔符(/),表示要忽略的问价在此目录下,而子目录中的问价不忽略
5、 如果名称的最后面一个是路径分隔符(/),表示要忽略的是此目录下该名称的子目录,而非文件(默认文件或目录都忽略)。

.ingrone 文件的内容参考

*.class
*.log
*.lock# Package Files #
*.jar
*.war
*.ear
traget/# iead
.iead/
*.iml*velocity.log*### STS ###
.apt_generated
.factorypath
.springBeans### IntelliJ IDEA ###
*.iml
*.ipr
*.iws
.idea
.classpath
.project
.settings/
bin/*.log
tmp/#rebel
*rebel.xml*

RabbitMQ

什么是RabbitMQ?

RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。

最大的特点就是消费并不需要确保提供方存在,实现了服务之间的高度解耦

核心(优点):

  • 解耦:消费并不需要确保提供方存在
  • 异步:confirm(确认)异步模式
  • 削峰

缺点:系统可用性降低、系统复杂度提高、数据一致性问题

小结

  • 如果一种消息有被某个系统订阅的, 那么Rabbit会发送到这个系统定义的队列中.
  • 如果订阅的系统宕机了, 那么RabbitMQ 还会发送到这个队列中中, 直到最后卡住整个MQ系统.(所以这里要慎重, 经常查看RabbitMQ的运行状况)
  • 如果无系统曾经订阅过某种类型的消息, 那么这个消息将会被丢弃.(所以这里开系统的时候一定要先上线消息订阅端. )

为什么要使用RabbitMQ?RabbitMQ的好处

  1. 在分布式系统下具备异步,削峰,负载均衡等一系列高级功能;
  2. 拥有持久化的机制,进程消息,队列中的信息也可以保存下来。
  3. 实现消费者和生产者之间的解耦。
  4. 对于高并发场景下,利用消息队列可以使得同步访问变为串行访问达到一定量的限流,利于数据库的操作。
  5. 可以使用消息队列达到异步下单的效果,排队中,后台进行逻辑下单。

RabbitMQ服务支持下列操作系统:Linux、WindowsNT 到 10、Windows Server2003 到 2016、macOS、Solaris、FreeBSD、TRU64、VxWorks
RabbitMQ支持下列编程语言:Python、Java、Ruby、PHP、C#、JavaScript、Go、ElixirObjective-C、Swift

使用 RabbitMQ 有什么好处?

1、服务间高度解耦
2、异步通信性能高
3、流量削峰

RabbitMQ 的使用场景有哪些?有哪些重要的组件?节点作用是什么?有哪些重要的角色?

使用场景:

  1. 服务间异步通信
  2. 顺序消费
  3. 定时任务,延迟信息处理(比如 10 分钟之后给下单未付款的用户发送邮件提醒)
  4. 请求削峰填谷,防止系统崩塌(例如:双十一的抢购活动)
  5. 解耦系统,对于新增的功能可以单独写模块扩展,比如用户确认评价之后,新增了给用户返积分的功能,这个时候不用在业务代码里添加新增积分的功能,只需要把新增积分的接口订阅确认评价的消息队列即可,后面再添加任何功能只需要订阅对应的消息队列即可。

RabbitMQ 有哪些重要的组件?

  • ConnectionFactory(连接管理器):应用程序与Rabbit之间建立连接的管理器,程序代码中使用。
  • Channel(信道):消息推送使用的通道。
  • Exchange(交换器):用于接受、分配消息。
  • Queue(队列):用于存储生产者的消息。
  • RoutingKey(路由键):用于把生成者的数据分配到交换器上。
  • BindingKey(绑定键):用于把交换器的消息绑定到队列上。

RabbitMQ 中 vhost(节点) 的作用是什么?

vhost(节点):每个 RabbitMQ 都能创建很多 vhost,我们称之为虚拟主机,每个虚拟主机其实都是 mini 版的RabbitMQ,它拥有自己的队列,交换器和绑定,拥有自己的权限机制。

RabbitMQ 有哪些重要的角色?

RabbitMQ 中重要的角色有:生产者、消费者和代理:

  • 生产者:消息的创建者,负责创建和推送数据到消息服务器;
  • 消费者:消息的接收方,用于处理数据和确认消息;
  • 代理:就是 RabbitMQ 本身,用于扮演“快递”的角色,本身不生产消息,只是扮演“快递”的角色。

RabbitMQ 消息的处理问题

RabbitMQ 的消息是怎么发送的?


首先客户端必须连接到 RabbitMQ 服务器才能发布和消费消息,客户端和 rabbit server 之间会创建一个 tcp 连接,一旦 tcp 打开并通过了认证(认证就是你发送给 rabbit 服务器的用户名和密码),你的客户端和 RabbitMQ 就创建了一条 amqp 信道(channel),信道是创建在“真实” tcp 上的虚拟连接,amqp 命令都是通过信道发送出去的,每个信道都会有一个唯一的 id,不论是发布消息,订阅队列都是通过这个信道完成的。

RabbitMQ 怎么保证消息的稳定性?

  • 提供了事务的功能。
  • 通过将 channel(信道) 设置为 confirm(确认)模式。

RabbitMQ 怎么避免消息丢失?

  • 把消息持久化磁盘,保证服务器重启消息不丢失。
  • 每个集群中至少有一个物理磁盘,保证消息落入磁盘。

数据的丢失问题,可能出现在生产者、MQ、消费者中

如何保证消息的顺序性

先看看顺序会错乱的场景:RabbitMQ:一个 queue,多个 consumer,这不明显乱了

要保证消息持久化成功的条件有哪些?RabbitMQ 持久化有什么缺点?

  1. 声明队列必须设置持久化 durable 设置为 true.
  2. 消息推送投递模式必须设置持久化,deliveryMode 设置为 2(持久)。
  3. 消息已经到达持久化交换器。
  4. 消息已经到达持久化队列。

以上四个条件都满足才能保证消息持久化成功。

持久化缺点:持久化的缺点就是降低了服务器的吞吐量,因为使用的是磁盘而非内存存储,从而降低了吞吐量。可尽量使用 ssd 硬盘来缓解吞吐量的问题。

如何确保消息正确地发送至 RabbitMQ? 如何确保消息接收方消费了消息?

发送方确认模式
将信道设置成 confirm 模式(发送方确认模式),则所有在信道上发布的消息都会被指派一个唯一的 ID。

一旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道会发送一个确认给生产者(包含消息唯一 ID)。

如果 RabbitMQ 发生内部错误从而导致消息丢失,会发送一条 nack(notacknowledged,未确认)消息。

发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消息。当确认消息到达生产者应用程序,生产者应用程序的回调方法就会被触发来处理确认消息。

接收方确认机制

接收方消息确认机制

消费者接收每一条消息后都必须进行确认(消息接收和消息确认是两个不同操作)。只有消费者确认了消息,RabbitMQ 才能安全地把消息从队列中删除。这里并没有用到超时机制,RabbitMQ 仅通过 Consumer 的连接中断来确认是否需要重新发送消息。也就是说,只要连接不中断,RabbitMQ 给了 Consumer 足够长的时间来处理消息。保证数据的最终一致性;

下面罗列几种特殊情况

如果消费者接收到消息,在确认之前断开了连接或取消订阅,RabbitMQ 会认为消息没有被分发,然后重新分发给下一个订阅的消费者。(可能存在消息重复消费的隐患,需要去重)

如果消费者接收到消息却没有确认消息,连接也未断开,则 RabbitMQ 认为该消费者繁忙,将不会给该消费者分发更多的消息。

如何避免消息重复投递或重复消费?

在消息生产时,MQ 内部针对每条生产者发送的消息生成一个 inner-msg-id,作为去重的依据(消息投递失败并重传),避免重复的消息进入队列;

在消息消费时,要求消息体中必须要有一个 bizId(对于同一业务全局唯一,如支付 ID、订单 ID、帖子 ID 等)作为去重的依据,避免同一条消息被重复消费。

消息基于什么传输?

由于 TCP 连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。RabbitMQ 使用信道的方式来传输数据。信道是建立在真实的 TCP 连接内的虚拟连接,且每条 TCP 连接上的信道数量没有限制。

消息如何分发?

若该队列至少有一个消费者订阅,消息将以循环(round-robin)的方式发送给消费者。每条消息只会分发给一个订阅的消费者(前提是消费者能够正常处理消息并进行确认)。通过路由可实现多消费的功能

消息怎么路由?

消息提供方——>路由——>一至多个队列

消息发布到交换器时,消息将拥有一个路由键(routing key),在消息创建时设定。

通过队列路由键,可以把队列绑定到交换器上。

消息到达交换器后,RabbitMQ 会将消息的路由键与队列的路由键进行匹配(针对不同的交换器有不同的路由规则);

常用的交换器主要分为一下三种

  • fanout:如果交换器收到消息,将会广播到所有绑定的队列上
  • direct:如果路由键完全匹配,消息就被投递到相应的队列
  • topic:可以使来自不同源头的消息能够到达同一个队列。 使用 topic交换器时,可以使用通配符

如何确保消息不丢失?

消息持久化,当然前提是队列必须持久化
RabbitMQ 确保持久性消息能从服务器重启中恢复的方式是,将它们写入磁盘上的一个持久化日志文件,当发布一条持久性消息到持久交换器上时,Rabbit 会在消息提交到日志文件后才发送响应。

一旦消费者从持久队列中消费了一条持久化消息,RabbitMQ 会在持久化日志中把这条消息标记为等待垃圾收集。如果持久化消息在被消费之前 RabbitMQ 重启,那么 Rabbit 会自动重建交换器和队列(以及绑定),并重新发布持久化日志文件中的消息到合适的队列。

RabbitMQ 怎么实现延迟消息队列?

延迟队列的实现有两种方式:

  • 通过消息过期后进入死信交换器,再由交换器转发到延迟消费队列,实现延迟功能;
  • 使用 RabbitMQ-delayed-message-exchange 插件实现延迟功能。

Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别?

对于吞吐量来说kafka和RocketMQ支撑高吞吐,ActiveMQ和RabbitMQ比他们低一个数量级。对于延迟量来说RabbitMQ是最低的。

  1. 从社区活跃度:按照目前网络上的资料,RabbitMQ 、activeM 、ZeroMQ 三者中,综合来看,RabbitMQ 是首选。
  2. 持久化消息比较:ActiveMq 和RabbitMq 都支持。持久化消息主要是指我们机器在不可抗力因素等情况下挂掉了,消息不会丢失的机制。
  3. 综合技术实现:可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统等等。RabbitMq / Kafka 最好,ActiveMq 次之,ZeroMq 最差。当然ZeroMq 也可以做到,不过自己必须手动写代码实现,代码量不小。尤其是可靠性中的:持久性、投递确认、发布者证实和高可用性。
  4. 高并发:毋庸置疑,RabbitMQ 最高,原因是它的实现语言是天生具备高并发高可用的erlang 语言。
  5. 比较关注的比较, RabbitMQ 和 Kafka:RabbitMq 比Kafka 成熟,在可用性上,稳定性上,可靠性上, RabbitMq 胜于 Kafka (理论上)。

另外,Kafka 的定位主要在日志等方面, 因为Kafka 设计的初衷就是处理日志的,可以看做是一个日志(消息)系统一个重要组件,针对性很强,所以 如果业务方面还是建议选择 RabbitMq 。

还有就是,Kafka 的性能(吞吐量、TPS )比RabbitMq 要高出来很多

RabbitMQ 的集群

镜像集群模式
你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,然后每次你写消息到 queue 的时候,都会自动把消息到多个实例的 queue 里进行消息同步。

好处:你任何一个机器宕机了,没事儿,别的机器都可以用。
坏处:

  1. 这个性能开销也太大了吧,消息同步所有机器,导致网络带宽压力和消耗很重!
  2. 这么玩儿,就没有扩展性可言了,如果某个 queue 负载很重,你加机器,新增的机器也包含了这个 queue 的所有数据,并没有办法线性扩展你的 queue

MQ 的缺点

  • 系统可用性降低

    系统引入的外部依赖越多,越容易挂掉,本来你就是 A 系统调用 BCD 三个系统的接口就好了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一MQ 挂了咋整?MQ 挂了,整套系统崩溃了,你不就完了么。

  • 系统复杂性提高

    硬生生加个 MQ 进来,你怎么保证消息没有重复消费?怎么处理消息丢失的情况?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已

  • 一致性问题

    A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要 是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,最好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了 10 倍。但是关键时刻,用,还是得用的

RabbitMQ 有几种广播类型?

  • direct(默认方式):最基础最简单的模式,发送方把消息发送给订阅方,如果有多个订阅者,默认采取轮询的方式进行消息发送。
  • headers:与 direct 类似,只是性能很差,此类型几乎用不到。
  • fanout:(扇出)分发模式,把消费分发给所有订阅者。
  • topic:匹配订阅模式,使用正则匹配到消息队列,能匹配到的都能接收到。

RabbitMQ 集群有什么用?

集群主要有以下两个用途:

  • 高可用:某个服务器出现问题,整个 RabbitMQ 还可以继续使用;
  • 高容量:集群可以承载更多的消息量。

RabbitMQ 节点的类型有哪些?

  • 磁盘节点:消息会存储到磁盘。
  • 内存节点:消息都存储在内存中,重启服务器消息丢失,性能高于磁盘类型。

RabbitMQ 集群搭建需要注意哪些问题?

  • 各节点之间使用“–link”连接,此属性不能忽略。
  • 各节点使用的 erlang cookie 值必须相同,此值相当于“秘钥”的功能,用于各节点的认证。
  • 整个集群中必须包含一个磁盘节点。

RabbitMQ 每个节点是其他节点的完整拷贝吗?为什么?

不是,原因有以下两个:

  • 存储空间的考虑:如果每个节点都拥有所有队列的完全拷贝,这样新增节点不但没有新增存储空间,反而增加了更多的冗余数据;

  • 性能的考虑:如果每条消息都需要完整拷贝到每一个集群节点,那新增节点并没有提升处理消息的能力,最多是保持和单节点相同的性能甚至是更糟。

RabbitMQ 集群中唯一一个磁盘节点崩溃了会发生什么情况?

如果唯一磁盘的磁盘节点崩溃了,不能进行以下操作:

  • 不能创建队列
  • 不能创建交换器
  • 不能创建绑定
  • 不能添加用户
  • 不能更改权限
  • 不能添加和删除集群节点

唯一磁盘节点崩溃了,集群是可以保持运行的,但你不能更改任何东西。

RabbitMQ 对集群节点停止顺序有要求吗?

RabbitMQ 对集群的停止的顺序是有要求的,应该先关闭内存节点,最后再关闭磁盘节点。如果顺序恰好相反的话,可能会造成消息的丢失。

redis和MQ如何平滑的扩容与缩容?

MQ的消息是存放在内存或者磁盘中的,在缩减集群数量时,必须要迁移节点的数据。增加节点时,要重新配置集群。这么看来是无法平滑缩容和扩容的。

MQ的消息生产比消费速度快得多,有什么解决方案吗?

生产消息比消费速度快得多,这个本身是没问题的,因为MQ的一个作用就是削峰。
如果要提高消费速度,可以增加多个消费者

【零散知识点总结4】相关推荐

  1. 【零散知识点总结2】

    大部分知识点来源于该博主--骆昊 知识点来源于网络,知道的可以在评论区贴上来源喔 <零散知识点总结1> 该文章涉及:Dubbo.HTTP和HTTPS.Mybatis.Hibernate. ...

  2. 【零散知识点总结1】

    大部分知识点来源于该博主--骆昊 知识点来源于网络,知道的可以在评论区贴上来源喔 <零散知识点总结1> 该文章涉及:Dubbo.HTTP和HTTPS.Mybatis.Hibernate. ...

  3. 【零散知识点总结3】

    大部分知识点来源于该博主--骆昊 知识点来源于网络,知道的可以在评论区贴上来源喔 <零散知识点总结1> 该文章涉及:Dubbo.HTTP和HTTPS.Mybatis.Hibernate. ...

  4. Effective C++ -- 零散知识点整理

    Effective C++ --1让自己习惯C++ Effective C++ --2构造/析构/赋值运算 Effective C++ --3资源管理 Effective C++ --4设计与声明 E ...

  5. 零散知识点小结(nginx/linux/mycat/redis/douubo/zookeeper)

    maven中jar包传输原则(了解) 问题:jar包文件 如何保证在远程传输的过程中不被别人篡改??? 算法介绍: SHA1算法 SHA-1(英语:Secure Hash Algorithm 1,中文 ...

  6. 【数据库】兴唐第二十八节课零散知识点汇总

    1.group by order by等都要放到语句的最后 2.表格标签: <table> <tr>表示行 <td>表示一个行里的单元格 </table> ...

  7. Thinkphp 零散知识点(caa/js路径,引入第三方类,ajax返回,session/cookie)

    一.关于JS和CSS路径问题 1.找路径是从入口文件index.php来找的,而不是从文件本身所在位置来找, 因为我们访问时是访问的入口文件 2.在存放JS和CSS的时候可以放到public文件夹下 ...

  8. Python零散知识点记录

    1.关于setdefaultencoding之前必须reload(sys): 要在调用setdefaultencoding时必须要先reload一次sys模块,因为这里的import语句其实并不是sy ...

  9. 系统分析师零散知识点

    数据库连接池技术 是指在系统初期或者初次使用时,完成数据库的连接,以后不再释放此连接,在处理后面的请求时,反复使用这些已经建立的连接. 这种方式可以大大减少数据库的处理时间,有利于提高系统的整体性能. ...

最新文章

  1. CentOS 为Tomcat安装系统级Apr
  2. 调用ajax_[WEB篇]-AJAX-02-AJAX应用案例
  3. 2019-11-23 Modern Family Scripts (01 “Pilot”)
  4. 同一个网络中为什么有些计算机可以连接共享打印机,有些需要输入密码,安装局域网共享打印机时,要求输入用户和密码,但对方并没有设置,为什么?谢谢!!...
  5. Zabbix 添加WEB监控(学习笔记十一)
  6. 【响应式编程的思维艺术】 (2)响应式Vs面向对象
  7. 用PHP实现多级树型菜单
  8. 【转】使用 OpenSSL API 进行安全编程 - 创建基本的安全连接和非安全连接
  9. Forrester报告:人工智能将取代6%的工作岗位
  10. 重载运算符operator
  11. 身高回归现象是否真的存在?
  12. 旭荣管理软件怎么修改小票内容_美萍超市管理软件——让管理回归轻松
  13. c 语言编程字谜,字谜游戏(a)C语言
  14. 软件测试技术课后习题:第4章白盒测试-广东高等教育出版社,主编杨胜利
  15. npm与package.json详解
  16. OpengL消除锯齿
  17. windows监听扬声器、麦克风静音、音量事件
  18. Win32设计图标、光标样式和窗口标题(简单易懂)
  19. 微信小程序背景图片真机不显示问题
  20. BS EN 438-5装饰用薄板材层压板材的分类和规范

热门文章

  1. 植物大战僵尸中文版修改器源码
  2. android 横向更多,改变传统打造视觉盛宴 Android四大桌面横向对比
  3. M3U8视频下载实现
  4. 【优化算法】猫群优化算法(CSO)【含Matlab源码 1071期】
  5. OKapi BM25算法
  6. 雾霾警醒世人,智慧城市加速刻不容缓
  7. 联想及华硕笔记本重装Windows10系统过程及难点记录
  8. 惠普HP P7-1005cx安装windows xp
  9. 20180130心情总结
  10. MC46-呆滞料分析报表用法