分类 编程 下的文章

高并发原则
1、垂直扩展:升配置
2、水平扩展:加机器

CAP原则
1、一致性:所有分区的数据保持一致。
2、可用性:服务永远可用。
3、分区容错性:一个分区崩溃不影响整体服务
一致性与可用性冲突

幂等性原则:不管请求多少次都返回一个结果。
去重表

数据共享原则
1、Session Replication
2、Session sticky:不支持高可用
3、独立Session服务器

无状态原则:将状态独立存储,使得应用服务无状态
redis存session,cdn放文件

1.JDK 和 JRE 有什么区别?
JRE: Java Runtime Environment
JDK:Java Development Kit
JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库。是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的。
JDK顾名思义是java开发工具包,是程序员使用java语言编写java程序所需的开发工具包,是提供给程序员使用的。JDK包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具:jconsole,jvisualvm等工具软件,还包含了java程序编写所需的文档和demo例子程序。
如果你需要运行java程序,只需安装JRE就可以了。如果你需要编写java程序,需要安装JDK。

2.== 和 equals 的区别是什么?
是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同
是指对内存地址进行比较 , equals()是对字符串的内容进行比较
指引用是否相同, equals()指的是值是否相同

3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
不一定。
两个对象equals相等,则它们的hashcode必须相等,反之则不一定。
两个对象==相等,则其hashcode一定相等,反之不一定成立。

4.final 在 java 中有什么作用?
1、修饰类:表示该类不能被继承;
2、修饰方法:表示方法不能被重写;
3、修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。
final修饰变量的本质: final修饰的变量会指向一块固定的内存, 这块内存中的值不能改变.

5.java 中的 Math.round(-1.5) 等于多少?
-1
Math的round方法是四舍五入,如果参数是负数,则往大的数如,Math.round(-1.5)=-1,如果是Math.round(1.5)则结果为2

6.String 属于基础的数据类型吗?
不属于。
Java8种基础的数据类型:byte、short、char、int、long、float、double、boolean。

7.java 中操作字符串都有哪些类?它们之间有什么区别?
String
StringBuffer
StringBuilder
这三个类都是以char[]的形式保存的字符串,
但是String类型的字符串是不可变的,对String类型的字符床做修改操作都是相当于重新创建对象.而对StringBuffer和StringBuilder进行增删操作都是对同一个对象做操作.
StringBuffer中的方法大部分都使用synchronized关键字修饰,所以StringBuffer是线程安全的,StringBuilder中的方法则没有,线程不安全,但是StringBuilder因为没有使用使用synchronized关键字修饰,所以性能更高,在单线程环境下我会选择使用StringBuilder,多线程环境下使用StringBuffer.
如果生命的这个字符串几乎不做修改操作,直接使用String,因为不调用new关键字声明String类型的变量的话它不会在堆内存中创建对象,直接指向String的常量池,并且可以复用.效率更高.

8.String str="i"与 String str=new String("i")一样吗?
不一样
String str = "i" 的方式,Java 虚拟机会将其分配到常量池中,而常量池中没有重复的元素,比如当执行“i”时,java虚拟机会先在常量池中检索是否已经有“i”,如果有那么就将“i”的地址赋给变量,如果没有就创建一个,然后在赋给变量;而 String str = new String(“i”) 则会被分到堆内存中,即使内容一样还是会创建新的对象。

9.如何将字符串反转?
1、使用String或StringBuffer/StringBuilder中的方法,
2、递归实现:
public static String reverse(String originStr) {

    if(originStr == null || originStr.length() <= 1)
        return originStr;
    return reverse(originStr.substring(1)) + originStr.charAt(0);
}

10.String 类的常用方法都有那些?
indexOf() 返回指定字符得索引
charAt() 返回指定索引处得字符
repalce() 字符串替换
trim() 去除字符串两端的空白
split() 分割字符串 返回分割后的字符串数组
getBytes() 返回字符串的byte类型数组
length() 返回字符串的长度
toLowerCase() 字符串转小写
toUpperCase() 字符串转大写
substring() 截取字符串
equals() 字符串比较

11.抽象类必须要有抽象方法吗?
不必须
抽象类必须有关键字abstract来修饰。
抽象类可以不含有抽象方法
如果一个类包含抽象方法,则该类必须是抽象类

12.普通类和抽象类有哪些区别?
抽象类不能被实例化
抽象类可以有抽象方法,抽象方法只需申明,无需实现
含有抽象方法的类必须申明为抽象类
抽象类的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类
抽象方法不能被声明为静态
抽象方法不能用 private 修饰
抽象方法不能用 final 修饰

13.抽象类能使用 final 修饰吗?
不能,抽象类是被用于继承的,final修饰代表不可修改、不可继承的。

14.接口和抽象类有什么区别?
抽象类要被子类继承,接口要被类实现。
接口只能做方法声明,抽象类中可以作方法声明,也可以做方法实现。
接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
接口是设计的结果,抽象类是重构的结果。
抽象类和接口都是用来抽象具体对象的,但是接口的抽象级别最高。
抽象类可以有具体的方法和属性,接口只能有抽象方法和不可变常量。
抽象类主要用来抽象类别,接口主要用来抽象功能。

15.java 中 IO 流分为几种?
Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。
字符流和字节流是根据处理数据的不同来区分的。字节流按照8位传输,字节流是最基本的,所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。
1.字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;
2.节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
读文本的时候用字符流,例如txt文件。读非文本文件的时候用字节流,例如mp3。理论上任何文件都能够用字节流读取,但当读取的是文本数据时,为了能还原成文本你必须再经过一个转换的工序,相对来说字符流就省了这个麻烦,可以有方法直接读取。
字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节, 操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!

16.BIO、NIO、AIO 有什么区别?
BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
适用场景分析
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂。

17.Files的常用方法都有哪些?
Files.exists() 检测文件路径是否存在
Files.createFile()创建文件
Files.createDirectory()创建文件夹
Files.delete() 删除文件或者目录
Files.copy() 复制文件
Files.move() 移动文件
Files.size()查看文件个数
Files.read() 读取文件
Files.write()写入文件

选择合适的字段,比如邮箱字段可以设为char(6),尽量把字段设置为notnull,这样查询的时候数据库就不需要比较null值

使用关联查询( left join on)查询代替子查询

使用union联合查询手动创建临时表

开启事物,当数据库执行多条语句出现错误时,事物会回滚,可以维护数据库的完整性

使用外键,事物可以维护数据的完整性但是它却不能保证数据的关联性,使用外键可以保证数据的关联性

使用索引,索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快的多的速度检索特定的行,特别是对于max,min,order by查询时,效果更明显

优化查询语句,绝大多数情况下,使用索引可以提高查询的速度,但如果sql语句使用不恰当的话,索引无法发挥它的特性。

第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。 
第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。
第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。

垃圾回收的过程首先就是要确定对象是否是垃圾对象,如果是垃圾对象,垃圾回收器才会进行回收。垃圾回收主要又两种算法:引用计数算法和可达性分析算法。

一、引用计数算法
引用计数算法就是在对象中添加了一个引用计数器,当有地方引用这个对象时,引用计数器的值就加1,当引用失效的时候,引用计数器的值就减1。当引用计数器的值为0时,jvm就开始回收这个对象。

简单的来说,在JVM中的栈中,如果栈帧中指向了一个对象,那么堆中的引用计数器的值就会加1,当栈帧这个指向null时,对象的引用计数器就减1。

这种方法虽然很简单、高效,但是JVM一般不会选择这个方法,因为这个方法会出现一个问题:当对象之间相互指向时,两个对象的引用计数器的值都会加1,而由于两个对象时相互指向,所以引用不会失效,这样JVM就无法回收。

二、可达性分析算法
针对引用计数算法的BUG,JVM采用了另一种方法:定义一个名为"GC Roots"的对象作为起始点,这个"GC Roots"可以有多个,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,即可以进行垃圾回收。

在上图中可以看到,如果时选用引用计数算法,object5, object6, object7之间互相引用,所以无法被回收。但是如果选用了可达性分析算法,虽然他们之间时相互引用,但是他们没有任何引用链和GC Roots连接,所以是可回收对象。

GC Roots对象一般包括有:
1.虚拟机栈(栈帧中本地变量表)中引用的对象;
2.方法区中类静态属性引用的对象;
3.方法区中常量引用的对象;
4.本地方法栈中JNI(Native方法)引用的对象。

三、拓展
对象被回收前的挣扎
在可达性分析算法中不可达的对象,并不是直接被回收,这时它们处于缓刑状态,至少需要进行两次标记才会确定该对象是否被回收:
 第一次标记:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记;
 第二次标记:第一次标记后接着会进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法(该方法可将此对象与GC Roots建立联系)。在finalize()方法中没有重新与引用链建立关联关系的,将被进行第二次标记。

 第二次标记成功的对象将真的会被回收,如果对象在finalize()方法中重新与引用链建立了关联关系,那么将会逃离本次回收,继续存活。如果没有建立联系, 在finalize()方法中执行该对象必须要执行的代码(因为该对象马上就要被回收),例如释放资源,这与try finally中finally的作用是一样的

方法区如何判断是否需要回收
方法区存储内容是否需要回收的判断可就不一样咯。方法区主要回收的内容有:废弃常量和无用的类。对于废弃常量也可通过引用的可达性来判断,但是对于无用的类则需要同时满足下面3个条件:

该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例;
加载该类的ClassLoader已经被回收;
该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
————————————————
版权声明:本文为CSDN博主「-小酒窝-」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zx1293406/article/details/104535414