什么是Java (定义 + 优点)
java是一个平台,由jvm和Java应用编程接口构成的一门面向编程语言。
不仅吸收了C语言的各种优点,还摒弃了c语言里面的多继承,指针等概念,因此java的特征主要有功能强大和简单易用的特征。
java语言作为静态面向对象编程的代表,实现了面向对象理论,以优雅的思维方式进行复杂的编程。
Java的优点(如何实现)
java加入内容
1.提供了对内存的自动管理,程序员不需要再进行分配,释放资源。
2.去除了c语言中的指针操作。
3.避免了赋值运算与逻辑运算的混淆。
4.取消了多重继承的复杂设施
优点
- 简洁有效
java语言省略了c语言中所有的难易理解,容易混淆的特性,如:头文件、指针、结构、单元、运算符重载、虚拟基础类。
它更严谨、简洁。
- 高可移植性
它可以同时在不同的系统上运行,同时还不用修改。
- 面向对象
java以对象的格式进行系统分析,系统设计,程序设计的一个体系
- 解释性
java语言就有解释性。相对于c语言,效率低、执行速度慢,正式通过在不同平台上运行java解释器,
来实现的一次编程到处运行的目标。
- 适合分布计算
java语言具有强大的、易于使用的连网能力,非常适合开发分布式计算的程序.
- 高性能
1.java语言源程序编写完成后,先使用java为编译器进行伪编译,将其转换为中间码(字节码),再解释。
2.提供了一种编译器(JIT),在需要更快的速度是,可以 使用JIT编译器将字节码转换成机器码,将其换成下来,来提高效率。
JIT编译器(just—In-Time):仅在运行时才进行,将其编译成为平台相关的机器码。
- 健壮性
java提供了在编译器若使用错误,在编译期则将会给你提示将错误暴露出来。
java语言还提供了程序稳定,健壮的特性,有效减少错误,这样使得java程序更加健壮。
- 具有多线程处理的能力
线程是一种轻量级的进程,是现代设计中必不可少的一种特性。
多线程处理能力使得程序能够具有更好的交互性,实时性。
-
安全性
-
动态语言
1.在java语言中,可以简单、直观的查询运行时的信息。
2.可以将新代码加入到一个正在运行的运行的程序中去。
- 跨平台
Java如何实现跨平台
回答流程:java运行流程 —引入jvm 解释
1.编译器: java经过编译生成.class字节码文件.
2.运行期: jvm加载并运行.class字节码文件.
3.java实现跨平台,java本身是不能实现跨平台的,它的实现主要依赖与JVM(java 虚拟机),但是jvm它本身也不会跨平台,
但它有多个版本的jvm,java 运行依赖于jvm 同时也实现了一次编译,随处运行的效果.
什么是jvm(概念 +作用)
jvm:java虚拟机。
它通过模拟一个计算机来达到一个计算机所具有的计算功能。
jvm能够跨计算机体系结构来执行java字节码,主要是由于jvm屏蔽了与各个计算机平台相关的软件或者硬件之间的差异,
使得与平台相关的耦合统一由jvm提供者来实现。
jvm的组成
1.类加载器:加载.class字节码文件
2.执行引擎:执行/运行.class字节码文件中包含的字节码指令,相当于实际机器上的CPU.
3.内存区:将内存划分成若干个区以模拟实际机器上的存储、记录和调度功能模块。
4.本地方法调用:调用c或者c++实现的本地方法的代码返回结果。
jvm执行流程
谈谈类加载器 ,有几种类加载器分别是什么
类加载器:用来加载java类到jvm中。
java源程序在经过java编译器之后就转换成java字节码文件
类加载器负责读取Java字节码代码,并转换成java.long.Class类的实例。
类加载器:(java适用的是系统类加载器)
1.2.3属于jvm 自带的类加载器。
1.引导类加载器:主要加载的是jvm自身需要的类,这个类加载使用C++语言实现的。
2.扩展类加载器:负责加载目录下或者由系统变量指定的类库。
3.系统类加载器:负责系统类路径或者指定路径的类库(常用到的classpath路径)、
通过grtSystemClassLoader()方法获取到该类的类加载器。
4.自定义类加载器:通过继承java.long.ClassLoader类的方式
类加载器之间的关系:
1.启动类加载器:由C++实现,没有父类。
2.扩展类加载器:由java语言实现,父类加载器为null;
3.系统类加载器:由java语言实现,父类加载器为ExtClassLoader(java适用)
4.自定义类加载器:父类加载器为AppClassLoader
双亲委派机制
原理:一个类加载器收到类加载器,它不会直接去加载,而是往父类上进行传递(若有多重继承会给顶级父类),
如果父类加载器可以完成,就成功返回;若父类无法加载任务,子加载器才会尝试去加载,这就是双亲委派模式。
作用:可以防止、避免类的重复加载,当父类已经加载该类后,子类没有必要再进行加载。
什么GC
GC:垃圾回收器
它是java虚拟机(JVM)提供的一种用于在空闲时间不定时回收任何对象引用占据的内存空间的一种机制。
回收的是无任何引用的对象占据的内存空间,而不是对象的本身。(只释放占用的内存空间)
使用GC垃圾一般什么时候被清理
何时回收
1.引用对象使用完成后
2.jvm触发GC(或者内存溢出会触发)
3.调用GC
如何触发GC方法
1.手动调用GC 调用命令:system.gc(); //注意:该语句只是通知,jvm希望执行垃圾回收,是否执行需要看jvm
2.jvm自动内存溢出
怎么监控GC是否执行
1.jvm参数检测: 在运行时,点击Config 添加-XX:+PrintGCDetails
2.重写finalize()在对象回收之前执行,可以作为监控。
fianlize()是Object类,子类可以覆盖该方法以实现资源清理工作
java中对象的引用
1.强引用:new 出来的对象,只要强引用还在,垃圾回收期永远不会回收该引用对象。
2.软引用:eg:是否记得高级流的使用需要低级流的支持(new(new());)。当系统内存不够用时,
这类引用关联的对象将会被回收。
3.弱引用:用来描述非须的对象,当GC执行执行时可能就会被回收。
4.虚引用:GC执行就会销毁 .主要作用记录对象的销毁。
软引用、强引用:缓存的产品的设计中
没有启动GC,对象可以会被回收吗----看分配对象
逃逸: 在某个方面创建的对象,除了在一方面使用,还被其他地方利用到,这样出现的后果是方法中创建的对象将不能回收。
(栈中存放小对象,堆中存放大对象)
java多数对象存放在堆中,对逃逸的小对象则会存在栈中。
未逃逸的在栈上,逃逸的在堆中。----此话有怀疑
java中添加GC的好处
1.与c语言相比,引入GC不用担心内存释放的问题。
2.GC有效防止内存的泄露,有效的使用内存。
JVM 、JRE 、JDK的区别
jvm:java 虚拟机
jre:java运行环境 =jvm + java类库
jdk:java开发工具包=jre + 开发工具
tomcat
定义: 是一个轻量级的应用服务器,是支持Servlet/jsp应用程序的容器,运行在jvm上,绑定IP地址监听TCP端口。
优点:占用资源小,扩展性好,支持负载平衡与邮件服务等开发应用系统常用的功能。
作用:
1.管理servlet应用的生命周期。
2.把客户端请求的url映射到对应的servlet
3.与servlet程序相结合处理HTTP请求。
java SE 部分
se的定义
SE: 允许开发和部署在桌面服务器,嵌入式环境和实时环境中使用的java应用程序。(电脑上运行软件)
八大基本类型
1.byte 1字节
2.short 2字节
3.char 2字节
4.int 4字节
5.long 8字节 (使用时+后缀 L)
6.float 4字节 (使用时+ 后缀 f)
7.double 8字节
8.boolean 4字节 (返回 true或者 false)
八大包装类型
1. byte-------Byte
2. char-------Character(特殊)
3. short-------Short
4. int-------Integer(特殊)
5. long-------Long
6. float-------Float
7. double-------Double
8. boolean-------Boolean
谈谈/如何实现自动拆装箱
自动拆装箱就是java在非人为的条件下,自动实现基本类型与包装类型的转换。
自动装箱:编译器调用valueOf()将原始类型值转换成对象;
自动拆箱时,编译器通过调用intvalue(),doubleValue()此类方法将对象转换为基本类型。
基本类型与包装类型的转换
1.new Integer(基本类型); 或者 Integer.valueOf(基本类型); ------基本类型转换为包装类型
2.intValue();------包装类型转换为基本类型(int 不固定)
3.parseInt(字符串格式);-------字符串转换为包装类型 (基于此方法可以转换为基本类型)
4.String.valueOf();-----基本类型/包装类型转换为字符串类型
八大基本类型为什么没有String
String 是final类型.属于对象,是个引用类型。
使用final类型后,变量不能发生修改,方法不可以重写,使用的类不能发生继承。
基本类型与引用类型的区别:基本类型只表示简单的字符或者数字,引用类型可以使任何复杂的数据结构。
在java虚拟机中,处理基础类型与引用类型的方式不一样,对于基本类型,java虚拟机会分配数据类型实际占有的内存空间
对于引用类型,仅仅是一个指向堆区中某个实例的指针。
String 与String Builder ,String buffer的区别
string :string声明的对象不可以发生改变,每次都会生成新的String对象,将指针指向新的String对象。
string builder 与string buffer:都是可变对象,相对于String都比较高效。 常用方法:append()追加,insert() 插入。
string Builder:线程不安全,但效率比String buffer 高。一般用在单线程。
string buffer:线程安全,效率相对较低一些,但它可用于多线程。
常用string 的方法
1.charAt(); 根据下标获取字符。
2.indexOf(); 根据字符可以获取下标
3.replace(); 可以将字符进行替换
4.trim(); 去除两边的空格。
5.toLowerCase(); 转换成小写
6.toUpperCase();转换成大写
7.length(); 获取长度
8.split(); 分割字符串。
9.subString(); 截取字符串
10.equals();字符串比较。
11.getBytes();获取byte类型数组。
12.isEmpty();判断字符串是否为空
13.startwith();判断开始字符
14.endswith();判断是否以当前字符串结尾
数组创建的几种方式
1.先声明再创建
例:String [] a = new String [length];
// 赋值
a[0] = ???;
2.声明的同时初始化
String [] a = new String[]{a,b,....}
3.直接初始化
String [] a = {a,b,...};
this与super的区别
共性:都不能在main()中。
this():在本类中使用。需要放在第一行,主要对构造方法的调用
super():用在子类中。必须用在构造方法的第一行,调用父类的构造方法
都放在第一行,因此this 与super不可以同时使用,
重载与重写的区别
重载overLoad: 组成:修饰词,返回值,方法名不发生改变,只对参数列表进行修改。一般会在构造方法上使用。
重写override: 组成:修饰词,返回值,方法名,及参数列表都不发生改变,方法体不同。一般会在多态,抽象和接口中常用。
抽象与接口的区别
实现:抽象的实现需要继承,接口需要实现接口,被抽象的方法都要重写。一般用于多态。
构造函数:抽象类可以有构造方法; 接口不能有。
main方法:抽象类可以有main方法,并且我们能运行它; 接口不能有main方法
抽象类是特殊的类。抽象中可以有普通的变量和方法。若方法变为抽象,则class上需要加上abstract。
接口是特殊的抽象类,由interface修饰,implements实现。它里面的变量默认是static final 常量,写的方法默认是抽象方法。
抽象类能使用final修饰吗
不能,定义抽象类就是让其他类继承的,如果定义为final该类就不能被继承,这样就彼此就产生矛盾,所以不能修饰抽象类。并且编辑器也会提示错误信息。
内部类与外部类的区别
(类中套类)
1.非静态内部类对象会持有外部类的对象。内部类可以直接访问外部类的私有属性和方法。
2.静态的内部类,不可以访问非静态成员。
向上造型与向下造型
向上造型:父类的引用指向子类的对象。目的:使用父类的共性。
向下造型:子类引用指向父类的对象(需要强转),目的:使用子类特有的属性
创建file常见方法(需要抛异常)
1.file.exists(); :检测文件是否存在
2.file.createFile(); :创建文件
3.file.createDirectory(); / file.mkdirs() :创建文件夹/多级文件夹
4.file.delete(); :删除一个文件或者目录
5.file.copy(); :复制文件
6.file.move(); :移动文件
7.file.size(); :查看文件个数
8.file.read(); 读取文件
9.file.write(); 写入文件
10.附加: 若前端往后端传输文件,获取文件名的方法: MultipartFile 的 getOriginalFilename(); // 文件名
IO流的分类,都有几种流
按功能:输入流(input),输出流(output)
按类型:字节流和字符流
字节流与字符流的区别:字节流按8位传输以字节位单位输入输出数据,字符流按16位传输以字符为单位输入输出数据。
BIO NIO,AIO的区别
1.BIO:同步阻塞式IO ,我们平常使用的传统IO,他的特点式模式简单使用方便,并发处理能力低。
2.NIO:同步非阻塞IO,传统IO的升级,客户端和服务端通过channel(通道)通讯,实现了多路复用。
3.AIO:是NIO的升级也叫做NIO2,实现了异步非阻塞IO,异步IO的操作基于事件和回调机制。
序列化与反序列化
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。
在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
序列化:利用ObjectOutputStream,对象的信息,按固定格式转成一串字节值输出并持久保存到磁盘化。
反序列化:利用ObjectInputStream,读取磁盘中序列化数据,重新恢复对象。
何为反射,在哪用到了反射
用来获取.class文件信息
创建反射有几种方法
3种:
1.以对象的形式构建反射。
例: Bean c = new Bean();
Class c1 = c.getClass(); // 返回是class
2.通过CLass类的forName() 获取反射
Class c1 = Class.forName(cn.com.Bean);
3.直接通过类名创建反射获取对象
CLass<Bean> c = Bean.class;
// 项目种哪里会使用
1.spring boot 项目上的启动项
2.jdbc连接时
Java容器
数组Array与ArrayList区别
1.Array是数组,ArrayList是集合。
2.Array的长度是定长的,若有变动需要新建数组,ArrayList可以变长。
3.Array可以容纳基本类型和对象,ArrayList只能容纳对象。
4.Array不能随意添加删除,而ArrayList可以任意的删除新增。
数组Array与ArrayList互转
1.Array转ArrayList
List l =Arrays.asList(参数是数组)
2.ArrayList转Array
String[] array = (String[])list.toArray(new String[size]);
ArrayList与LinkList的区别
相同点实现List接口
ArrayList(查询): 线程不安全,查询速度快,访问效率高,增删数据效率降低。数据结构是动态数组结构。
LinkList(增删): 线程不安全,增删数据快,两端效率高,底层数据结构是链表结构。
ArrayList如何实现扩容
当添加第一个元素时,size为0,得到minCapacity为1,判断数组的数据是不是空,如果是空将传进来的值和默认大小值进行比较,获取两个的最大值,当前可以得到 minCapacity变为10
List线程不安全如何解决
集合中:
Vector:线程安全。
ArrayList:线程不安全
如何变为线程安全的:
可以使用Collection.synchronizedList(....)保证线程安全
HashSet 与HashMap 的区别
HashSet :存储的无序的集合,但输出是有序的(声明:LIST是有序的)
HashMap :存储的是键值对 k(key) - v(value)格式
HashMap与LinkedHashMap 与HashTable的区别
hashMap: 最常用的Map,根据键的hashCode值进行存储数据的,访问速度较快,获取的数据顺序是随机的,存储key仅可以有一个null值,若key重复则是覆盖。
LinkedHashMap :在遍历的时候比hsahMap的速度慢,但是输出和输入的顺序相同。
HashTable:与hasemap类似,但是不允许有null
HashMap 的存储方式(k相同时/v相同时)
HashMap 的存储方式时key-value
当key相同时,value则会发生覆盖,key必须保证唯一。
当value相同时,若key相同,则发生覆盖,若key不同,则就可以正常插入。
并行与并发
并发:多个程序抢占了同一个cpu资源,形成资源被抢占的现象。如:秒杀。
并行:有多个CPU,每个CPU只负责一件事情,没有发生抢占现象。
线程与进程
线程:是操作系统中能够进行运算调度的最小单位,是进程种实际运作单位。一个进程可以有多个线程。
特点:随机性(cpu随机切换)
进程:每运行一个程序至少运行一个进程,程序所占用的内存。
特点:
1.独立性:拥有自己独立的资源,每一个进程都有自己的私有空间。
2.动态性:进程是一个正在运行系统的活跃的指令集合。
3.并发性:多个线程可以再单个处理并发执行,多个线程之间不会互相影响。
目的:解决高并发
实现线程 的几种方式
存在2种方式:
1.class类继承(extends) Thread
2.class类实现(implements) Runnable
共同点:需要重写run()
@override
public void run(){}
启动方式 :
Class class = new Class();
Thread t = new Thread(class);
t.start();
若是继承的:可以创建完类 直接调用start()启动线程。
线程的状态/生命周期
1.创建状态(new):在生成线程对象,并没有调用对象的start().
2.就绪状态(Runnadle):当调用了线程的start()之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程。
3.运行状态(thread):线程的调度程序执行当前线程。
4.阻塞状态(sleep):线程正在运行,被暂停,通常是为了等待某个时间发生的某项资源之后再进行。
导致线程阻塞的方法:sleep(睡眠),suspend(被另一个线程阻塞),wait(正在等待) 等都可以导致线程阻塞。
5.死亡状态(Dead):线程的run()执行结束或者调用stop(),该线程就会死亡。
run()与start( )的区别
run(): 就是调用的普通方法。
start(): 用来启动线程,真正实现多线程的运行
谈谈什么是死锁
定义:在使用多线程时,2个或2个以上的运算,各自占有的一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致都是在等待对方释放资源,导致产生死锁。
产生的条件:
1.互斥。
2.持有并请求。
如何进行避免:
1.固定加锁顺序
2.只针对共享的部分进行锁住。
3.使用定时锁。 在获取锁时使用tryLock(),当等待时间较长时,使用该方法不会一直等待,而是返回错误信息,能有效的避免死锁的问题。
线程池的创建
可以创建4种:
1.[Fixed:(fei si d ) 固定的]new FixedThreadPool(int nThreades): 创建一个固定长度的线程池,每当提交一个任务就会创建一个线程,当线程发生未逾期的错误而结束时,线程会补充一个新的线程。
2.[cached: (kai chi d) 隐藏]new CacheThreadPool(): 创建一个可缓存的线程池。若线程池规模超过了处理需求,将自动回收空闲进程,当需求增加时,可以自动添加新的线程。
3.[SingLe: (sen gou )单一的]new SingLeThreadExcutor(): 单线程的Executor,创建单个工作线程来执行任务,若出现异常结束,会创建一个新的线程来代替它,特点能确定依照任务在队列中的顺序来串行。
4.[Scheduled: (sha jiu d )计划]new ScheduledThreadPool(int corePoolSize): 创建一个固定长度的线程池。而且以延迟或者定时的方式来执行任务。
线程池的状态及关闭方法
1.running:线程池的初始状态是running,处于running状态时,可以接受新任务。
2.shoudown:此状态不接受新的任务,但能处理已经添加的任务。
3.stop:不接受新任务,不处理已添加的任务,会中断正在处理的任务。
4.tidying:所有任务终止,进入tidying状态,trminated:线程池会彻底终止或者关闭。
关闭线程池的方法:执行trminated
同步锁的理解
同步锁:为了保证每个线程都能正常执行原子不可更改操作,同步监听对象/同步锁/同步监听器/互斥锁的一个标记锁.
语法:同步代码块锁住共有部分
synchronized(对象){ 需要同步的代码; }
对象:
1.若是本类,可以使用this
2.可以先在共享代码块 创建共有的对象,并将引用赋予对象
例:
class MyTickets implements Runnable {
int tickets = 100;
Object obj = new Object();
@Override
public void run() {
// 方式1 synchronized (this) {
//方式2
synchronized (obj) {
while (true) {
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + tickets--);
} else {
break;//<=0就结束
}
}
}
}
}
调用方法:
public class Test extends Thread{
public static void main(String[] args) throws IOException {
MyTickets target = new MyTickets();
Thread t2 = new Thread(target, "窗口2:");
Thread t1 = new Thread(target, "窗口1:");
Thread t3 = new Thread(target, "窗口3:");
Thread t4 = new Thread(target, "窗口4:");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
谈谈面向对象OOP(封装,继承,多态)
封装(class):把相关的数据封装成一个类。
继承(extends):是子类自动共享父类属性和方法,这是类之间的一种关系。目的:提高重用性。
多态(抽象):增强软件的灵活和重用性。
谈谈程序技术器
虚拟机字节码指令的地址或者Undefined
用到的设计模式
1.单例设计模式:
原理:通过一定的程序设计手段,实现整个工程只有一个唯一的实例。
分为:饿汉式和懒汉式
回答的时候,要答到三元素
1.构造方法私有化
2.静态属性指向实例
3.public static的getlnstance方法,返回第二步的静态属性
饿汉式:
public class Test extends Thread{
public static void main(String[] args) throws IOException {
Design data = Design.getData();
Design data2 = Design.getData();
System.out.println(data==data2);
}}
class Design {
// 设置访问的范围:使用public private
private Design() {
System.out.println("调用的方法");
}
// 使用静态创建对象,静态的需要才可以进行调用
static private Design myTickets= new Design();
// 提供外界访问数据及按钮
public static Design getData(){
return myTickets;
}
懒汉式:
public class Test extends Thread{
public static void main(String[] args) throws IOException {
Design data = Design.getData();
Design data2 = Design.getData();
System.out.println(data==data2);
}}
class Design {
// 设置访问的范围:使用public private
private Design() {
System.out.println("调用的方法");
}
// 使用静态创建对象,静态的需要才可以进行调用
static private Design myTickets;
// 提供外界访问数据及按钮
//--修饰成synchronized 方法,是用来解决线程安全隐患问题,降低了访问效率。
public static synchronized Design getData(){
if (myTickets == null) {
myTickets = new Design();
}
return myTickets;
}
}
Erro 与Exception 的区别
1.Error和Exception都是继承Throwable
2.Exception是程序正常运行中,可以预料的意外情况,可以被捕获,进行相应的处理.
3.Error 是指正常情况下,不大可能出现的情况,绝大部分的Error 都会导致程序处于非正常的,不可恢复的状态, 不需要捕获, 常见的OutOfMemoryError 是Error的子类.
try-catch-finally 可以去掉哪一个,Why
finally。
前面的主要是判断已成的出现,若无异常则执行try中的数据否则执行catch
finall是不管是否正常都是需要执行的
一般用于关闭对象,如:执行文件流完成后需要逐个进行关闭
final 、finally 、finalize区别
fianl:修饰词。用于声明属性,方法和类,分别表示属性不可变值,方法不可覆盖,类不可继承。
finally:是异常处理语句结构的一部分,表示总是执行。在异常处理时提供Finally块来执行任何清除操作。
finalize:方法名。是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收。
常见异常
1.空指针异常 --NullPointerException.
2.数组下标越界异常 --ArrayIndexOutOfBoundsException
3.算数异常 --ArithmeticException
4.类型转换异常 --ClassCaseException
5.文件找不到异常 -- FileNotFoundExption
6.参数异常 --IllegalArgumentException
java EE 部分
EE的含义
EE:企业级帮助开发和部署可移植,健壮,可伸缩安全的服务器java应用程序。(一般用于做网站)
扩展:
ME:在移动设备和嵌入设备上运行的程序提供一个健壮且具有灵活的环境。(使用做评论)
Java SE 、EE、ME的区别
Java SE(Java Platform,Standard Edition)。Java SE 以前称为
J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的 Java 应用程序。Java SE 包含了支持 Java Web服务开发的类,并为 Java Platform,Enterprise Edition(Java EE)提供基础。
Java EE(Java Platform,Enterprise Edition)。这个版本以前称为
J2EE。企业版本帮助开发和部署可移植、健壮、可伸缩且安全的服务器端 Java 应用程序。Java EE 是在 Java SE的基础上构建的,它提供 Web 服务、组件模型、管理和通信 API,可以用来实现企业级的面向服务体系结构(service-oriented architecture,SOA)和 Web 2.0应用程序。
Java ME(Java Platform,Micro Edition)。这个版本以前称为 J2ME。Java ME 为在移动设备和嵌入式设备(比如手机、PDA、电视机顶盒和打印机)上运行的应用程序提供一个健壮且灵活的环境。Java ME包括灵活的用户界面、健壮的安全模型、许多内置的网络协议以及对可以动态下载的连网和离线应用程序的丰富支持。基于 Java ME 规范的应用程序只需编写一次,就可以用于许多设备,而且可以利用每个设备的本机功能。
sql语句格式
使用命令进入数据库:mysql -h127.0.0.1 -uroot -p
1.创建库 /删除库
//创建
create database 库名;
或者 create database if not exists 库名;
或者 指定字符集 create database if not exists 库名 charset utf8;
//删除
drop database 库名;
或者 drop database if exists 库名;
2.创建表/删除表
//创建
1.set names gbk; (使用cmd为什么需要设置字符集? 原因:在windows的cmd默认编码是GBK,在MySql里面按照UTF-8编码存储数据的,所以cmd不支持自然就乱码了)
2.create table 表名(列名 数据类型,id int ,name varchar(20),brithday date score double);
设置主键约束,不设置自增 : create table 库名 (id int primary Key,name varchar(20),......);
设置主键自增 : create table 库名 (id int primary Key auto_increment ,name varchar(20),......);
2.1后续加入主键自增 :
顺序:1.先添加主键 2,再添加自增 (注意:1如果没有之间,不可以添加自增 2.只有主键为数值时,才可以添加自增)
1.添加主键:alter table 表名 modify(修改的意思) id int primary Key;
2.添加自增(主键必须为数值)alter table 表名 modify id int auto_increment;
2.2单独删除主键自增:
顺序:1.删除自增 2.删除主键
1.删除自增:alter table 表名 modify id int;
2.删除主键:alter table 表名 drop primary key;
//删除
drop table stu;
或者 drop table if exists 库名;
3.CRUD语句
C(增): insert into 表名(列)values(值); 或者 insert into 表名 values(全部值都需要写);
R(查): select *(最好不适用*)from 表名 +索引
U(改):update 表名 set column=value...where column1=value1
D(删):delete from 表名 where ...(筛选条件)
sql优化
方法:
1定位:查看慢的原因
2分析:看语法和索引
3调试:看使用情况
sql调优:1.慢查询 2.索引 3.拆分表
1.查询尽量避免使用“*”来代替查询内容,应获取什么数据查询什么数据,目的为了提高效率。
2.在业务密集的sql中尽量不采用IN 操作符,用exists代替。
3.模糊查询Like
尽量避免%在开头使用,会对全表进行扫描,除非想要提高查询效率。
4.尽量避免在where子句中进行!= 或者>,< 或者or操作符,否则会对全表进行扫描。
5.尽量避免在where子句中为unll值做判断--会扫描全表。
6.尽量避免子查询多使用join连接。
7.where与having的比较应尽量使用where。 原因:where是先经过对数据的过滤,数据少了然后进行分组(group by)/排序(order by)。
8.事务:若有失败,则不发生改变,保持原有数据。
9.char 与 varchar尽量使用 varchar 不会占用无用内存----等同于字符串中的trim()。
(扩展:
1.where 与having区别:
(1):相同点:都是对记录进行筛选过滤。
(2):异同点:1.where 在分组之前,对记录进行筛选过滤,并且where字句中不能使用多行函数以及列别名。
2.having 是在分组之后,对记录进路筛选过滤,并且having字句中可以使用多行函数以及列别名,表别名。
2.char(n)、varchar(n)、text 都表示字符串类型,区别在于:
(1):char(n):在保存数据时,如果存入的字符串长度小于 指定长度的话n,后面会用空格补全,因此可能造成空间浪费,单char的存储速度比varchar与text快。
(2):varchar(n):在保存数据时,按照实习的真实长度存储,剩余的空间可以留给别的数据用,varchar 不会浪费空间。适合存储长度不固定的数据
(3):text:大文本类型,一般文本超过255个字符,就会使用text类型存储。
3.获取当前时间 (类型:date 年月日 time:时分秒 dataTime:年月日 时分秒 timestamp:时间戳(实际存储的是一个时间的ms值))
sql的聚合函数
SUM(求和)、AVG(平均值)、MAX(最大值)、MIN(最小值)、COUNT(计数)
sql的关联方式
sql设计范式
如何避免数据重复插入
设置唯一索引
使用ignore或者replace into 或者 on duplicate key update
1.on duplicate key update :若数据库存在会触发的更新操作,执行语句update.
Insert into tb_addrbook(num,name,mobile)value('1001','小李','13245623223')ON DUPLICATE KEY UPDATE name='小李',mobile='13245623223';
2.replace into :数据库存在就删除再插入
REPLACE INTO 'student'('name','age')values('jack',18);
3.insert ignore into :数据存在则忽略此次插入数据
INSERT IGNORE INTO 'student'('name','age')values('jack',18);
sql的赃读,幻读,不可重复的区别
1.脏读: 一个事务读到另一个事务未提交的更新数据。
2.不可重复读: 一个事务两次读同一行数据,可是这两次读到的数据不一样。
3.幻读: 一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
事务的特性
原子性
事务的原子性是指事务必须是一个原子的操作序列单元。事务中包含的各项操作在一次执行过程中,只允许出现两种状态之一,要么都成功,要么都失败。
任何一项操作都会导致整个事务的失败,同时其它已经被执行的操作都将被撤销并回滚,只有所有的操作全部成功,整个事务才算是成功完成。
一致性
事务的一致性是指事务在执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处以一致性状态。
比如:张三给李四转钱,不可能张三被扣了钱,李四没有加钱。
隔离性
事务的隔离性是指在并发环境中,并发的事务是互相隔离的,一个事务的执行不能被其它事务干扰。也就是说,不同事物并非操作相同数据时,每个事务都有完整的数据空间。
一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务是不能互相干扰的。
持久性
事务的持久性是指事务一旦提交后,数据库中的数据必须被永久的保存下来。即使服务器系统崩溃或服务器宕机等故障。只要数据库重新启动,那么一定能够将其恢复到事务成功结束后的状态。
JDBC的创建流程
SQL中${}与#{}的区别
${} 和 #{} 都是 MyBatis 中用来替换参数的。
区别:
功能不同:
${} 是将参数直接替换到 SQL 中。
#{} 则是使用占位符的方式,用预处理的方式来执行业务
使用场景不同:
在类型上#{}可以传递所有类型,但是${},可能会存在语法错误报错。
在自定义排序上,使用#{}会存在报错,需要进行${}拼接使用查询。
当传递的是普通参数时,需要使用 #{} 的方式,而当传递的是 SQL 命令或 SQL 关键字时,需要使用 ${} 来对 SQL 中的参数进行直接替换并执行。
安全性不同:
${} 会出现安全问题, SQL 注入的问题。
#{} 因为是预处理的,所以不会存在安全问题。
sql注入攻击的解决方法
JDBC与My Batis 的区别
HTTP 与HTML 的定义
HTML执行流程
js的定义
jsp定义
jsp:全称java Server Pages 是一种动态网页开发技术。使用jsp标签在HTML网页插入java代码。
标签常用:<% %>
jsp与servlet的区别
jsp是servlet的一种简化。
1.jsp经编译后就变成了servlet.
2.jsp更擅长表现于页面显示,servlet更擅长逻辑控制。
3.servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpservletResponse对象以及HttpServlet对象得到。
4.Servlet则是完整的javal类,这个类的service方法用于生成对客户端的响应。
5.servlet的应用逻辑是在java文件中,并且完全从表现层中的HTMl里分离出来。
6.jsp的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。
7.jsp侧重于视图,servlet主要用于控制逻辑。
8.servlet更多的是类似于Controller用来控制。
jsp执行流程
1.客户端发出Request请求。
2.Jsp Container 将JSP转译成Servlet的源代码。
3.将产生的servlet源代码经过编译后,并加载到内存执行。
4.把结果Respone(响应)至客户端。
servlet的定义
servlet:一门动态Web资源开发技术。
是java servlet的简称称为服务器连接器,用java编写的服务端程序,具有独立于平台和协议的特性是一个java类。
javaWeb中的servlet主要功能是承载网络连接,业务逻辑处理,比如一些编码格式的转换、登录拦截等。
侠义的servlet是指Java语言实现的一个接口,广义的servlet是指任何时间这个servlet接口的类。
静态web:(html,css,js等)
动态web:(servlet,jsp,.net,php等)
作用:对服务接收过来的请求进行处理。
servlet执行流程
生命周期:创建实例化--调用实例init()--调用service()服务--调用销毁方法destroy()--jvm调用垃圾回收机制
1.当tomcat启动时,会加载web.xml文件。然后再加载站点下的每个web应用的web.xml文件。
2.查询本地hosts文件查询域名和ip的映射;若找不到联网到运营商的dNS服务器找域名和ip映射。
3.在当前web名称应用下的web.xml文件中查找是否存在匹配的url-pattern
4.使用servlet的内部名称在web.xml文件中查找是否存在相同名称的servlet配置
5.得到对应的servlet-class内容
6.通过反射构造,调用方法。
servlet的九大内置对象
1.application:服务器启动后就产生这个对象,所有客户共享这个内置的application对象
2.page(this):当前被访问的jsp页面的实例化。实际使用的是jsp转换成的servlet。
3.request:封装用户请求信息,请求可以转发给其他的request。
4.response:处理后的数据返回客户端,请求可以重定向(url不一致,在处理时发生变化)
5.out:用于发送输出流到客户端。
6.session:存储客户端请求的信息,因此它是有状态的交互的。
7.config:包含了当前的JSP/servlet所在的weB应用的配置信息。
8.pagecontext:提供访问jsp页面命名空间。它是提供用来访问其他的jsp隐含对象。
9.exception;用于捕获jsp抛出的异常,它只有在jsp页面属性ISErrorPage= true时才可用。
servlet的(4个)作用域
application:全局作用范围。整个应用程序共享,就是在部署文件中的同一个webApp共享,生命周期:应用程序启动到停止。
session:会话。当用户首次访问时,产生一个新的会话,以后服务器就可以记住这个会话的状态。生命周期:会话超时或者服务器强制使会话失效。
request:请求作用域,就是客户端的一次请求。
page:一个jsp页面。
servlet的生命周期
1.创建实例化。servlet容器负责加载和实例化. 解释:当服务器servlet容器启动时或者检测到需要这个servet来响应第一个请求时,由servlet容器通过java反射API创建Servlet实例。
2.调用init(); 进行初始化
3.service(); 进行执行处理客户端的请求
4.destory(); 销毁。
5.最后,servlet是由JVM的垃圾回收器进行垃圾回收。
cookie 与session 的定义与区别
request 与response的定义 与区别
get 与post 的区别
主要区别体现在参数传输过程。
1.get提交:将数据通过问号?拼接在地址栏URL地址的后面,相对非常不安全,并且数据量有限制。通常不能超过1kb或者4kb.
2.PoSt提交:是通过请求实体将数据提交给服务器,不会显示在地址栏,因此相对更加安全。
重定向(redirect)与转发(forward)的区别
介绍一下ssm
什么是My Batis 有什么作用
Mybatis与Jpa的区别
相同点:都是java持久层API。
不同点:
1.层级划分: myBatis中的Dao层是mapper ,Jpa的dao层是repository(储存库)
2.操作上: myBatis是对象与结果集的映射,Jpa是对象与对象之间的映射。
3.学习复杂程度上: myBatis更易于上手,Jpa则相比较难一些。
4.使用上:myBatis可以自定义sql也可以在mapper层使用@select注解,jpa则是在Mapper层使用@Query注解注入sql
介绍一下Spring
spring是一个开源轻量级的框架,spring的核心主要两部分:1.AOP(面向切面对象,扩展功能不修改源代码实现) 2.IOC(控制反转,降低耦合度 DI依赖注入)
spring的优点
1.方便解耦,简化开发 :
2.AOP编程的支持:
3.生命事务的支持:
4.方便程序测试:
5.方便集成各种优秀框架:
6.降低了java EE API的使用难度:
7.java源码经典学习范例:
spring中bean 的声明周期
spring的核心 与核心内容是什么
在这里插入代码片
IOC
AOP
DI依赖注入的几种方式
构造方法注入
setter注入
注解注入
oop 与 Aop的区别
什么是spring mvc ?有什么作用
Spring MVC的三个特征
spring MVC 的执行流程
1.json 怎么转换的 :后端:使用@ResponseBody
spring MVC 的几个组件
spring mvc 核心组件:
1.DispatcherServlrt:中央控制器/前端控制器 :由框架提供,在web.xml中配置
作用:接受请求,响应结果,相当于转发器。
2.HandlerMapping:处理器控制器 :由框架提供
作用:根据请求的Url查找Handler(处理器/controller),可以通过XML和注解方式来映射。
3.HandlerAdapter:处理器适配器:由框架提供
作用:按照特定的规则,去执行Handler(处理器)
4.handler(处理器)/controller (需要开发)
作用:接受用户请求信息,调用业务方法处理请求 ,也称后端控制器
5.model and View :视图解析器 由框架提供
作用:进行视图解析,把逻辑视图解析成物理视图。
6.view 视图:需要开发
作用:将数据展现在页面。
架构(spring,sprongBoot,myBatis,springMvc,mybatisPlus,springColud)各作用
spring:
Spring是一个开源的企业级Java应用程序开发框架,它提供了一套全面的基础架构,以帮助开发者更容易地构建可伸缩的Web应用程序。
Spring的主要作用如下:
1. IoC(控制反转)容器:Spring的核心是IoC容器,它负责对象的创建、销毁和管理。传统的开发方式中,对象的创建和销毁都是由开发者手动管理的,而通过使用Spring的IoC容器,对象的声明周期完全交由Spring管理,开发者只需要定义对象的配置信息,Spring会根据配置信息自动创建对象,并在不需要时进行销毁,大大减少了开发工作量。
2. AOP(面向切面编程):Spring通过AOP模块提供了对切面编程的支持,可以将横切关注点(如日志记录、事务管理等)从核心业务逻辑中分离出来,提高代码的可维护性和重用性。通过使用Spring的AOP功能,开发者可以自定义切点,将横切逻辑织入到核心逻辑中。
3. 数据访问抽象:Spring提供了对各种数据访问技术的抽象,包括JDBC、ORM框架(如Hibernate、MyBatis)和NoSQL数据库。通过Spring的数据访问抽象,开发者可以通过配置简单地切换不同的数据访问技术,不需要修改业务逻辑代码,提高了代码的灵活性和可扩展性。
4. Web应用开发:Spring提供了一套完整的Web应用开发框架,包括MVC框架、RESTful Web Service支持和Web容器集成。通过Spring MVC框架,开发者可以快速开发出高性能、易扩展的Web应用程序,通过RESTful Web Service支持,开发者可以基于HTTP协议构建出面向资源的Web服务,并进行跨平台的数据交互。
5. 安全性:Spring提供了一套完善的安全性框架,包括身份验证、授权和数据加密等功能。开发者可以通过配置简单地集成安全性功能到应用程序中,保护数据的安全性和完整性。
6. 事务管理:Spring提供了对事务管理的支持,可以轻松地管理分布式事务,确保数据的一致性。通过Spring的事务管理功能,开发者可以声明式地管理事务,无需编写繁琐的代码,大大减少了开发工作量。
7. 测试支持:Spring提供了一整套测试支持,包括单元测试、集成测试和性能测试等。通过Spring的测试支持,开发者可以快速编写测试用例,自动化地进行各种测试,保证程序的质量和稳定性。
总之,Spring作为一个强大的企业级Java应用程序开发框架,提供了一套全面的基础架构,可以帮助开发者更容易地构建可伸缩的Web应用程序。无论是对象的管理、AOP的支持、数据访问抽象、Web应用开发、安全性、事务管理还是测试支持,Spring都提供了强大的功能和丰富的API,大幅度提高了开发效率和代码质量。
sprongBoot:
Spring Boot是一个开源的Java框架,主要用于简化和加速基于Java的应用程序的开发。它提供了一套开发工具和约定,使得构建独立、可执行的、生产级别的Spring应用变得更加容易。
Spring Boot的主要目标是简化Spring应用程序的配置和部署过程,减少开发者在项目搭建和配置上的工作量,从而让开发者能够更专注于业务逻辑的实现。
Spring Boot具有以下特点和功能:
自动配置:Spring Boot根据应用程序的依赖和配置自动进行配置,减少了手动配置的工作量。
内嵌服务器:Spring Boot可以内嵌Tomcat、Jetty等Web服务器,简化了部署和启动过程。
简化的依赖管理:Spring Boot提供了一套统一的依赖管理机制,可以简化依赖的引入和版本管理。
组件化:Spring Boot采用了模块化的设计,可以根据需求选择性地引入各种功能组件,如数据库访问、安全性等。
强大的开发工具支持:Spring Boot集成了许多开发工具,如自动重载、热部署等,提高了开发效率。
健康检查和监控:Spring Boot提供了健康检查和监控功能,可以监控应用程序的运行状态和性能指标。
生产就绪性:Spring Boot提供了各种特性和配置选项,以确保应用程序在生产环境中的稳定性和可靠性。
总而言之,Spring Boot使得开发者可以更快速、更便捷地构建和部署Java应用程序,提高开发效率和项目的可维护性。它适用于各种类型的应用程序,包括Web应用、RESTful服务、批处理作业等。
myBatis
MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。以下是MyBatis的作用和特点的详细介绍:
1、简化数据库访问操作;2、提高开发效率;3、灵活的sql定制;4、缓存机制;5、与其他框架的集成。mybatis的特点:1、简单易用;2、映射简单;3、灵活性高;4、性能高效;5、支持自定义sql、存储过程以及高级映射;6、简化crud操作;7、缓存功能;8、易于维护;9、多平台使用;10、丰富的插件支持。
一、作用:
1、简化数据库访问操作:MyBatis的设计初衷是为了简化数据库访问操作,提供更便捷的数据库操作方式。通过MyBatis,开发者可以更轻松地操作关系型数据库,避免了大量繁琐的JDBC代码和手动设置参数以及获取结果集的过程。
2、提高开发效率:MyBatis简化了数据库访问的代码编写过程,将数据库操作和SQL语句与Java代码解耦。通过XML或注解的方式配置SQL语句,使得代码更加清晰和易于维护,降低了数据转换的复杂性,提高了开发效率。
3、灵活的SQL定制:MyBatis支持原生SQL、动态SQL和存储过程,因此在数据库访问过程中具有很高的灵活性。开发人员可以根据需要编写复杂的查询语句,不受框架的限制,能够完成复杂查询和特殊优化的需求。
4、缓存机制:MyBatis提供了一级缓存和二级缓存,可以显著提高数据库查询的性能。缓存可以减少对数据库的频繁访问,提升应用程序的响应速度。
5、与其他框架的集成:MyBatis可以与Spring等流行的Java框架无缝集成,使得数据库操作和业务逻辑可以更好地组织在一起,简化了应用程序的开发过程。
二、特点:
1、简单易用:MyBatis通过XML配置文件和注解,让开发者能够轻松地将SQL语句与Java代码分离,使得代码结构更清晰、易于维护。
2、映射简单:MyBatis提供了简单的映射方式,可以将数据库表中的字段自动映射到Java对象的属性上,降低了数据转换的复杂性。
3、灵活性高:MyBatis支持动态SQL和存储过程,对于一些需要执行复杂查询的应用场景,提供了强大的动态SQL支持,使得查询条件可以根据需要进行灵活拼装,便于处理多变的查询需求。
4、性能高效:MyBatis是一个轻量级的框架,它直接映射SQL语句和Java方法,没有额外的开销,因此在大部分情况下,其性能较高。
5、支持自定义SQL、存储过程以及高级映射:MyBatis允许开发者直接编写原生态SQL,满足各种复杂的查询需求。同时,它还支持存储过程以及高级映射功能。
6、简化CRUD操作:MyBatis简化了对数据库中数据的增删改查操作,通过配置文件和注解的方式即可完成对数据库的操作。
7、缓存功能:MyBatis内置了缓存机制,可以在一定程度上提高系统的性能。
8、易于维护:MyBatis的映射文件和注解方式使得代码结构清晰,易于维护。同时,MyBatis还提供了日志功能,可以帮助开发者更好地调试和维护程序。
9、多平台使用:MyBatis可以应用于各种数据库平台,如MySQL、Oracle、SQL Server等。同时,它还可以与Spring等框架无缝集成,具有广泛的应用场景。
10、丰富的插件支持:MyBatis提供了丰富的插件支持,可以扩展其功能。例如,有插件可以帮助开发者实现分页功能、性能监控等。
总之,MyBatis是一个强大且灵活的持久层框架,适用于各种规模的Java应用程序。它简化了数据库访问操作,提高了开发效率和应用程序的性能和可维护性。
springColud
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
Spring Cloud 的五大组件分别是:
Eureka:服务发现与注册。
Ribbon:客户端负载均衡。
Feign:声明式服务调用。
Hystrix:断路器,提供熔断机制等。
Config:分布式配置管理。
前端向后端传递方法
后端向前端传递方法
maven
tomcat
什么是单体架构
分布式架构是什么
微服务架构定义
dubbo框架
跨域的几种方法,怎么实现的
高可用与高并发的区别
怎么实现负载均衡
谈谈redis缓存
缓存类型5种:
1.String:字符串
2.List:列表
3.Hash:哈希
4.Set:无序集合
5.Zset:有序集合
常见出现的问题:击穿,穿透,雪崩
缓存穿透:查询不存在的数据,为空的数据时,导致缓存和数据库都无法命中。建议将空数据存到缓存中去,但不要太久
缓存击穿:缓存中不存在但数据库中存在的数据(热点key过期),大量请求直接访问数据库。建议:自动更新或定时刷新缓存中的热点key。使用互斥锁:在访问数据库前,使用互斥锁确保同一时间只有一个线程能够访问数据库,其他线程则等待锁释放后再从缓存中获取数据。
缓存雪崩:大量缓存数据同时失效,导致数据库压力过大。建议:设置不同的过期时间:避免缓存同时失效。主从架构与集群。限流与降级
redis在项目中如何配置
1.添加pom依赖
方式一、
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--Spring boot end-->
<!--spring2.0集成redis所需common-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>${commons-pool2.version}</version>
</dependency>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jedis.version>2.9.0</jedis.version>
<commons-pool2.version>2.5.0</commons-pool2.version>
</properties>
方式二、
<!-- jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
<!--添加spring-datajar包 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
2.启动redis
注册redis服务: redis-server --service-install redis.windows.conf
启动服务:redis-server --service-start
停止服务:redis-server --service-stop
删除服务:redis-server --service-uninstall
3.在配置文件配置属性
spring:
redis:
host:127.0.0.1 #服务器地址
database:0 #数据库索引
port:6379 #服务器连接端口,默认
password: #服务器连接密码可以是空
timeout: #连接超时时间(ms)
4.在启动类上添加注解@EnableCaching注解
含义:@EnableCaching注解是spring framework中的注解驱动的缓存管理功能。自spring版本3.1起加入了该注解。如果你使用了这个注解,那么你就不需要在XML文件中配置cache manager了。
当你在配置类(@Configuration)上使用@EnableCaching注解时,会触发一个post processor,这会扫描每一个spring bean,查看是否已经存在注解对应的缓存。如果找到了,就会自动创建一个代理拦截方法调用,使用缓存的bean执行处理。
5.在ServiceImpl类中使用相关注解来实现缓存功能。
查询使用: @Cacheable
新增使用: @CachePut
修改、删除使用: @CacheEvict
6.储存Json格式数据
原因:如果不对redis中的数据格式进行设置,缓存的内容将类似乱码形式,可以通过给redisTemplate设置JSON格式的序列化器,并通过配置RediscacheConfiguration设置超时时间。在Redis中存储标准json格式,通过过期时间筛选不必要的缓存,以便节约空间。
在config中新建BaseRedisConfig配置类
注册中心有哪些,区别是什么
集群搭建流程
微服务
集成工具
使用spring cloud 的 优点与缺点
前端基本知识
冒泡排序
// 思想:相邻的数据进行对比,并互换值。
int [] a = {8,6,8,7,3};
// 思路先实现一次的转换
for(int i=0; i< a.length-1;i++) {
for(int j =0; j<a.length-1-i; j++){
// 转换
if(a[j]>a[j+1]){
int tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
}
}
}
// 打印数组
System.out.println(Arrays.toString(a));
选择排序
// 思想:始终相邻的进行比较
int [] a = {8,6,8,7,3};
for (int i = 0; i < a.length ; i++) {
for (int j = i+1; j < a.length; j++) {
if (a[i]>a[j]) {
int tmp = a[i];
a[i]= a[j];
a[j] = tmp;
}
}
}
System.out.println(Arrays.toString(a));
插入排序
int [] a = {8,6,8,7,3};
for (int i = 1; i < a.length; i++) {
int j = i;
while (j>0) {
if (a[j]<a[j-1]) {
int tmp = a[j];
a[j]= a[j-1];
a[j-1]=tmp;
j--;
} else {break;}
}
}
System.out.println(Arrays.toString(a));
使用Stream流排序
int [] a ={8,6,8,7,3};
IntStream stream = Arrays.stream(a);
IntStream nums3 = stream.sorted();
Stream boxedNums = nums3.boxed();
Stream<Integer> sortedNums = boxedNums.sorted();
IntStream temp = sortedNums.mapToInt(Integer::intValue);
int[] ints = temp.toArray();
System.out.println(Arrays.toString(ints));