Java 知识点 合

一、java基础

1.java语言的优势

java是一种跨平台,适合于分布式计算环境的面向对象编程语言。

特性:面向对象、平台无关、简单性、多线程、可靠、安全

1)面向对象:封装、继承、多态

封装:是用一个自主式框架把对象的数据和方法联在一起形成一个整体。

对象是支持封装的手段,是封装的基本单位。

继承:一个对象直接使用另一个对象的属性和方法,

是面向对象编程中的一种代码复用的方式。只支持单继承。

多态:“一个对外接口,多个内在的实现方法” 2)平台无关:java主要靠java虚拟机实现平台无关。

3)简单性:java相对于C++语言比较简单。

4)多线程:java内置多线程控制,简化多线程应用程序的开发。

5)可靠:java是强类型的语言,要求显式的方法声明,

保证了编译器可以发现方法调用错误,保证程序更加可靠;

java不支持指针,杜绝了内存的非法访问;GC防止内存泄漏问题;

  1. 安全:java通过自己的安全机制防止病毒程序的产生和下载程序对本地系统的

威胁破坏;

2.变量:

1)java中变量就是变化数值的载体

2)注意事项:

1.已经声明的变量不能再次声明

2.为变量赋值必须匹配类型

3.必须先声明再初始化才能使用

3)变量的命名:

规则:

  1. 允许字母、数字、_、$做变量名的组成部分,数量不限,

数字不允许开头;

2.不能包含空格

3.大小写敏感

4.关键字不能做变量名

规范:

1.使用英文单词命名

2.见名知意

3.多个单词组成时:驼峰命名法

3.数据类型:

基本数据类型、引用数据类型

基本数据类型:

byte short int long float double boolean char

字节 1 2 4 8 4 8 1   2

取值范围 -2^7~2^7-1 -2^15~2^15-1 -2^31~2^31-1 -2^63~2^63-1 true false 0~65535

 

直接量:直接编写在代码中的数字,整型是int,小数是double

4.运算符和表达式:

算数运算符:+ - * / %

关系运算符:> < >= <= == !=

逻辑运算符:&& || !短路特性

赋值运算符:=

复合赋值运算符:+= -= *= /= %=(内置强制类型转换)

字符串连接符:+

自增自减运算符:++ --

条件运算符(三目运算符):boolean?true:false

5.程序结构:

1)顺序结构:编写的每行代码一定会执行一次

2)分支结构:编写的代码可能会执行一次

单分支:if

双分支:if-else

多分支:if-else if 特别适合于判断一个值在一个范围的情况

switch case default 使用灵活,结构简单,运行效率高,适合于等值判断

3)循环结构:编写的代码可能会执行多次

要素:循环变量、循环条件、循环操作、变量更新

while

do while

for

循环次数固定首选for循环

循环次数不确定:一定会至少执行一次的do while

有可能一次都不执行的while

循环中的流控语句:break,continue

循环嵌套:break或continue作用是内层循环,可以使用标记跳出指定循环

6.数组:是一组相同数据类型的数据的集合

数组的构成:数组名、数组元素、数组长度、数组下标

特征:

1)数组的长度是固定的

2)数组中只能保存相同数据类型的数据

3)数组元素是有默认值的

数组的复制:

System.arraycopy();

Arrays.copyOf();

数组的排序:

Arrays.sort();//结果为升序

7.方法:程序中,处理一个功能或业务的代码块

1)为什么要用方法:

1.将处理不同业务的代码从程序入口中分离出来,降低代码复杂度

2.每个方法专心的编写自己的业务,不和其他业务干扰

3.各种方法在main方法中调用,方便团队开发

4.方法可以编写一次,调用多次

2)方法的定义:

1.无参无返回值

2.无参有返回值

3.有参无返回值

4.有参有返回值

二、面向对象

减少代码冗余,提高程序的可维护性和可扩展性

1.重载:方法名相同,参数列表不同(可以发生在同一类,也可以发生在父子类)

  重写:方法名,参数列表相同,返回值类型如果是void或基本数据类型,

则返回值类型也要相同,如果是引用类型,可以是父类返回值类型的子类。

访问权限不能比父类更严格。

2.构造方法:

构造方法主要作用是给成员变量赋值

1)构造方法是创建对象时会执行的方法,名称与类名相同,不声明返回值类型

2)如果某个类没有显式的定义构造方法,则编译器会自动添加一个公有的、无参

数的构造方法,如果已经显式的定义构造方法,则编译器不会干预。

3)构造方法是可以重载的,某个类中可以同时存在多个构造方法

 

构造方法的应用场景:

1)创建类的对象,快速的设置相关属性的值;

2)限制对象的创建过程,甚至不允许直接创建对象;

3)通过在构造方法中添加参数,强制要求得到某些数据;

3.this关键字

1)调用当前对象的属性

2)调用当前对象的方源

3)调用当前类的构造,必须编写在当前类构造方法中的第一行

super关键字

   构造方法的第一行如果不写this()或super(),默认为super();

final关键字

 修饰类:不允许被继承

 修饰方法:不能被重写

修饰成员变量:不允许被修改,在被对象实例化之前必须被赋值(声明的同时赋值

,构造方法中赋值);

修饰局部变量:只能被赋值一次(修饰形参);

修饰引用数据类型:属性值可以变,引用不能变化;

static关键字

静态变量保存在方法区,每个类只能存一份,使用类名调用

静态方法没有也不能使用this,不能重写

静态块:无论实例化多少对象,只运行一次,最先运行(JVM加载这个类时运行)

常量

常量被使用时,在编译时就确定值,运行时直接使用,提高运行效率

命名规范:所有字母均大写,使用_来分割单词

一般声明的同时赋值,也可以在静态块中赋值,但不推荐,因为效率低。

4.抽象方法

特征:1)抽象方法不能编写方法体

2)抽象方法必须在子类中被重写,除非子类也是抽象类

abstract和final不能同时修饰类或方法

5.内部类:在一个类中,又编写了另一个类

成员内部类可以使用4种访问修饰符

成员内部类中的方法可以访问外部类中的私有成员

外部类可以中方法中实例化内部类对象,并访问内部类的私有成员

所有内部类在编译之后,都会产生自己独立的class文件

 

匿名内部类:

1.通常编写在方法中

2.可以使用外部类中的私有成员

3.方法中不能修改局部变量的值,局部变量只能被赋值一次,jdk1.6之前

所有局部变量都必须使用final修饰

6.接口

使用接口能实现java中的多继承

接口中的所有属性都是:公有静态常量

方法是:公有抽象方法(jdk1.8之后可以有普通方法)

接口中不允许有构造方法,不能实例化

7.垃圾回收机制的优点和不足:

优点:java程序员,不需要考虑垃圾回收的问题

缺点:

1.垃圾回收管理机制本身是占用内存的

2.垃圾回收的时机,并不是立即的

3.垃圾回收的机制,只能回收java程序中产生的垃圾,在其他媒介中产生

的垃圾要手动回收

判定规则:内存中保存对象被引用的个数为0

 

final

修饰类:不允许被继承

修饰方法:不能被重写

修饰成员变量:不允许被修改,在被对象实例化之前必须被赋值(声明的同时赋值

,构造方法中赋值);

修饰局部变量:只能被赋值一次(修饰形参);

修饰引用数据类型:属性值可以变,引用不能变化;

 

finally

java的一种异常处理机制,finally结构中的代码总会执行

 

finalize

是Object类中编写的一个方法,被垃圾回收管理机制在回收这个对象前调用

 

三、JavaSE

1.String

1.支持正则表达式

1)boolean matches(String regex)

使用给定的正则表达式匹配当前字符串是否符合格式要求,符合则返回true

2)String replaceAll(String regex,String str)

将当前字符串中满足正则表达式的部分替换为给定内容

3)String split(String regex)

将当前字符串中挖宝按照满足正则表达式的部分拆分,然后将拆分后的字符串

以数组形式返回

2.char charAt(int index)

获取当前字符串中指定位置对应的字符

3.int indexOf(String str)

查找给定字符串在当前字符串中的位置,若当前字符串中不包含给定内容则返

回值为-1

4.int length()

获取当前字符串的长度

5.String substring(int start,int end)

截取当前字符串中指定范围的字符串

6.boolean startsWith(String str)

   boolean endsWith(String str)

判断字符串是否以给定的字符串开始或结尾的

7.String valueOf(XXX xxx)

String静态方法,作用是将给定的内容转换为字符串

8.String trim()

去除当前字符串两侧的空白字符

9.String toUpperCase()

  String toLowerCase()

将当前字符串中的英文部分转换为全大写或全小写

10.StringBuilder

String str="";

StringBuilder builder=new StringBuilder(str);

builder.append("需要填加的字符");//增

builder.delete(x,x);//删

builder.replace(x,x,"修改后的字符");//改

builder.insert(x,"需要填加的字符");//插

System.out.println(builder.toString());

2.Integer(包装类)

1.int d=0;

  Integer in=Integer.valueOf(d);

  int i=in.intValue();

2.String str="123";

  int i=Integer.parseInt(str);

3.int imax=Integer.MAX_VALUE;

3.file

1.File file=new File(目录);//获取名为file的文件

   boolean file.exists();//判断文件是否已存在

   file.createNewFile();创建file文件

   file.getName();//获取文件名

   file.length();//获取长度

   file.getAbsolutePath();//获取绝对路径

   boolean file.canRead();//是否可读

   boolean file.canWrite();//是否可写

   boolean file.isHidden();//是否为隐藏文件

   boolean file.isFile();//是否为文件

   boolean file.isDirectory();//是否为目录

   File[] file.listFiles();//获取当前目录中所有子项

2.过滤器

   File file=new File(".");

   FileFilter filter=new FileFilter(){

public boolean accept(File pathname){

String name=pathname.getName();

return name.startsWith(".");

}

   };

   File[] subs=file.listFile(filter);

3.删除文件、目录

  File file=new File(./test.txt);

  file.delete();

4.创建目录

  mkdir()  mkdirs()

4.raf(基于指针)

1.RandomAccessFile raf=new RandomAccessFile("文件路径","rw");

   raf.write(1);//向文件写入1字节

   raf.close();

   RandomAccessFile raf=new RandomAccessFile("文件路径","r");

   raf.read();//读取1字节文件

   raf.writeInt();//写入4字节  --  raf.readInt();

   raf.writeLong();                --  raf.readLong();

   raf.writeDouble();             -- raf.readDouble();

   raf.seek(x);//将指针移动到x下标位置

   raf.getFilePointer();//返回指针下标位置

2.写入字符串

   RandomAccessFile raf=new RandomAccessFile("文件路径","rw");

   String line="";

   byte[] data=line.getBytes("UTF-8");

   raf.write(data);    ||    raf.write(data,x,x)//每次写入固定长度的字节

3.读取字符串

   byte[] data=new byte[(int)raf.length()]

   raf.read(data);

   String str=new String(data,"UTF-8");||(data,x,x,"UTF-8")

5.io

1.FIS--FOS   文件流

2.ISR--OSW  转换流:负责衔接字符高级流与字节流

3.OIS--OOS  对象输入输出流

4.BW--BR  缓冲流

5.PW  缓冲流(自动行刷新)

6.Thread(线程)

1.Thread t=new Thread(){

public void run(){

}

   };

   t.start();

2.Runnable r=new Runnable(){

public void run(){

}

   };

   Thread t=new Thread(r);

   t.start();

3.currentThread();    获取线程   

4.getName();  获取名字

5.long   getId();   获取唯一标识

6.int getPriority();   获取优先级    setPriority();设置优先级

7.boolean isAlive();   线程活着

8.boolean isDaemon();  线程死了

9.boolean isInterrupted();   线程中断

10.setDaemon(true);   设置守护线程要在线程启动前进行

11.join();  sleep();阻塞    interrupt();打断阻塞

12.synchronized  同步块

synchronized(类名.class) 静态方法

它们最大本质的区别是:

sleep()不释放同步锁,wait()释放同步锁.   

还有用法的上的不同是:sleep(milliseconds)可以用时间指定来使他自动醒

过来,如果时间不到你只能调用interrupt()来强行打断;wait()可以用notify()

直接唤起.

13.线程理论:

1.进程:操作系统进行资源调度和分配的基本单位(例如:浏览器,APP,JVM);

2.线程:进程中的最小执行单位;

3.并发:多线程抢占CPU,可能不同时执行,侧重于多个任务交替执行;

4.并行:线程可以不共享CPU,可每个线程一个CPU同时执行多个任务;

5.线程的状态:新建状态,就绪状态,运行状态,阻塞状态,死亡状态;

static String content;

public static void main(String[] args)throw new Exception{

Thread t = new Thread(){

public void run(){//运行状态

content = "helloworld";

};//run方法执行结束线程处于死亡状态

};//新建状态

t.start();//就绪状态(可运行状态)

//Thread.sleep(1000);//主线阻塞

//t.join();//让t线程执行结束,主线程阻塞

while(content == null){

Thread.yield();//让当前线程放弃CPU,处于就绪状态

}

System.out.println(content.toUpperCase());

}

  1. 多个线程并发执行时,仍旧能够保证数据的正确性,这种现象称之为线程  安全;
  2. 多个线程并发执行时,不能够保证数据的正确性,这种现象称之为线程不安全;

8.synchronized排他锁(独占锁,非公平锁);

9.实例方法默认锁是this,静态方法默认锁是类名.class;

10.volatile:禁止指令重排序;

11.导致线程不安全的因素有哪些?

1)多个线程并发执行;

2)多个线程并发执行时存在共享数据集(临界资源);

3)多个线程在共享数据集上的操作不是原子操作(不可拆分);

12.如何保证并发线程的安全性?

1)对共享进行限制访问(例如加锁:syncronized,Lock):多线程在同步

方法或同步代码块上排队;

  1. CAS(比较和交换)实现非阻塞同步(基于CPU硬件技术支持),

CAS算法支持无锁状态下的并发更新,但可能会出现ABA问题,长时间自旋问题;

  1. 取消共享,每个线程一个对象实例(例如threadlocal),connection、

SimpleDateFormate、SqlSession不允许线程共享,需要使用threadlocal;

class Counter02{

private volatile int count;

//公平锁,独占锁,排他锁

private Lock lock = new ReentrantLock(true);

public void count(){

lock.lock();//加锁

try{

count++;

}finally{

lock.unlock();//解锁

}

}

}

class Counter03{

//底层使用CAS算法(基于CPU硬件实现,内存地址、期望数据值、需要更新的值)

private AtomicInteger at = new AtomicInteger();

public void count(){

at.incrementAndGet();

}

}

class DateUtils{

private static ThreadLocal<SimpleDateFormate> td = new ThreadLocal<>();

public static String format(Date date){

//从当前线程获取SimpleDateFormat对象

SimpleDateFormate sdf = td.get();

if (sdf != null){

return sdf.format(date);

}

//当前线程没有则创建SimpleDateFormat并且存入当前线程

sdf = new SimpleDateFormate("yyyy/MM/dd");

td.set(sdf);//ThreadLocal关联了一个线程,线程中有一个Map,key为td(ThreadLocal)

return sdf.format(date);

}

}

13.Synchronized:基于Monitor对象实现同步;

14.Synchronized锁优化:锁的级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态;锁可以升级不可以降级;

15.volatile:一般用于修饰属性变量

1)多核或多cpu场景下保证变量的可见性。

2)禁止指令的重排序操作

3)不保证原子性

16.在JMM中如果一个操作A Happened——before 另一个操作B,那么A操作的结果对B操作的结果是可见的,那么我们称这种方式为happened——before原则 ;

17.JMM中基于happened——before规则,判定数据是否存在竞争,线程是否安全,以及多线程环境下变量值是否是可见的;

18.JAVA中为了保证多线程并发访问的安全性,提供了基于锁的应用,大体可归纳为两大类,即悲观锁和乐观锁;

悲观锁:假定会发生并发冲突,屏蔽一切可违反数据完整性的操作,同一时刻只能有一个线程执行写操作。

syncronized,lock,ReadWriteLock

适合写操作比较多的场景,写可以保证写操作时数据正确;

乐观锁:假设不会发生冲突,只在提交操作时检查是否违反数据完整性,多个线程可以并发执行写操作,但只能有一个线程写操作成功。

CAS算法

适合读操作比较多的场景,不加锁的特点能够使其读操作的性能大幅提升;

19.减少多线程上下文切换的方案:

1)无锁并发编程:锁的竞争会带来线程上下文的切换;

2)CAS算法:CAS算法在数据更新方面,可以达到锁的效果;

3)使用最少线程:避免不必要的线程等待;

4)使用协程:单线程完成多任务的调试和切换,避免多线程;

20.如何避免死锁?

1)避免一个线程中同时获取多个锁;

2)避免一个线程在一个锁中获取其他的锁资源;

3)考虑使用定时锁来替换内部锁机制,如lock.tryLock(timeout);

7.collection(集合)

1.collection:

Collection<> c=new ArrayList<>();

c.add();   填加元素  返回值boolean类型

c.size();   返回集合元素个数

boolean c.isEmpty();   是否为空集

c.clear   清空集合

c.addAll(集合);  

boolean containsAll(集合)  判断是否全包含集合   contains();

removeAll(集合)  删除共有元素   remove();

遍历集合:

1)for(元素类型:集合){

 }

2)迭代器

 Iterator<> it=c.iterator();

 while(it.hasNext()){

String str=it.next();

 }

2.List<>list=new ArrayList<>();

   E get(int index);  获取给定下标处对应的元素

   E set(int index,E  e);  将给定元素设置到指定位置上,返回值为原位置对应的元素

   list.add(int index,"");指定位置插入元素

   list.subList();   子集

   Collections.sort(list);  排序

   Collections.sort(list,new comparator<>(){

 

   });

3.数组转集合

  List<>list=Arrays.asList(数组);

  List<>list2=new ArrayList<>(list);

4.集合转数组

  String[] arr=list.toArray(new String[list.size()]);

5.Map<key,value>map=new HashMap<>();

   map.put();//成对填加元素

   map.get();//查询

   map.containsKey(key);// 检查map中是否包含指定key

6.Set<Entry<key,value>> set = map.entrySet();

   getKey();

   getValue();

7.集合理论:

1.Collection:集合的父接口 Collections:是针对集合的帮助类,提供了一系列

静态方法实现集合的排序等。

1.List:

有序,可重复

get,set,subList,toArray,asList

  1. ArrayList:采用数组方式存储数据,允许直接序号索引元素,索引

数据快,插入数据慢,数组长度增长率为目前长度的50%,线程

不安全

  1. Vector:数组长度增长率为目前长度的100%,线程安全,性能比

ArrayList差

3)LinkedList:采用双向链表实现存储,插入数据快,索引数据慢

2.Set:

无序,不能重复

2)HashSet:(无序)是哈希表实现的,允许存入一个null值,要求存入的对象必须实现hashCode()

底层是HashMap

3)TreeSet:(有序)是二叉树实现的,里面的数据是自动排好顺序的,不允许存入null值

2.Map:

键值对、键唯一、值不唯一

1.HashMap:是最常用的Map,根据键的HashCode值存储数据,线程不安全

LinkedHashMap:保存了记录的插入顺序

2.Hashtable:线程安全,效率低,不允许键或者值为null

3.TreeMap:能够把保存的记录根据键排序,默认是升序,不允许key为空,线程不安全

3.遍历:

List:ListIterator,for,foreach

Set:Iterator,foreach

Map:

keySet(),entrySet(推荐)

四、框架

1.springboot配置拦截器

1)创建拦截器类实现HandlerInterceptor接口,重写prehandle方法

2)创建配置类实现WebMvcConfigurer接口,重写addInteceptors方法

2.购物车逻辑

1)根据传递过来的商品id和用户id查询数据库购物车表中的商品信息

2)结果为null:将数据封装到购物车实体类,执行插入操作

3)不为null:获取结果中的商品数量、购物车id,将数量重新计算执行修改操作

 

 

 

 

1.Git

工作区:保存项目的元数据和对象数据库的地方

暂存区:保存下次将提交的文件列表信息

版本库:本地版本库

远程仓库:可以看做是github,它是一个远程仓库

命令:

git clone <url> 克隆远程版本库

git init 初始化本地版本库

git add . 跟踪所有改动过的文件

git remote add <remote> <url> 添加远程版本库

git commit -m "commit message" 提交所有更新过的文件

git push <remote> <branch> 上传代码及快速合并

git pull <remote> <branch> 下载代码及快速合并

git log 查看提交历史

git config --global user.name "name"

git config --global user.email "email"配置身份信息

git reset --hard "UUID" 回退版本

git push -f -u origin master  强制提交到远程仓库

2.Servlet:

Servlet是用来扩展web服务器功能的组件

Servlet是如何运行的:

1.浏览器依据ip、port建立连接

2.浏览器将相关数据打包,发送请求

3.容器解析请求数据包,并且将解析到的数据封装到request对象,

同时创建一个response对象。

4.容器创建servlet对象,然后调用该对象的service方法。

(容器会将request和response作为参数传进来,可以通过

request获取请求参数,也可以将处理结果放到response

对象中)

5.容器读取response对象中的处理结果,然后将处理结果打包发送

给浏览器。

6.浏览器解析响应数据包,生成响应的页面

Servlet的生命周期

实例化,初始化,就绪,销毁

Servlet中,可以保存数据三个不同的作用域是:request,session,application

HTTP协议

网络应用层协议,规定了浏览器与服务器之前是如何通信以及相应数据包的格式

如何通信:建立连接,发送请求,发送响应,关闭连接

重定向与转发的区别:

1)共享request和response,转发可以,重定向不可以

2)转发是一次请求组件间的数据,重定向是两次请求不共享组件间的数据

3)重定向的地址栏的地址改变,转发不会

4)重定向的新地址是任意的,转发的新地址必须是同一个应用内的地址

 

  JSP:是java服务器端动态页面技术

向JSP中添加java代码的三种方式

java代码片段、jsp表达式、jsp声明<%!  %>

JSP隐含对象:out,request,response,session,application,pageContext

page,config,exception

隐含对象的作用:可以简化http请求响应信息的时间

JSP中常用的指令:page,include,taglib

状态管理:cookie session

 

3.Class.forName()和Class.loadClass()的区别

forName("")得到的class是已经初始化完成的

        loadClass("")得到的class是还没有连接的

4.CAP理论

一致性指更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致,所以,一致性,说的就是数据一致性。

可用性:每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据

分区容错性: 分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。

5.BASE理论是对CAP理论的延伸,BASE是指基本可用、软状态、最终一致性。

基本可用是指分布式系统在出现故障的时候,允许损失部分可用性。

响应时间上的损失:正常情况下搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障(比如系统部分机房发生断电或断网故障),

查询结果的响应时间增加到了1~2秒。

功能上的损失:购物网站在购物高峰(如双十一)时,为了保护系统的稳定性,部分消费者可能会被引导到一个降级页面。

软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据会有多个副本,允许不同副本同步的延时就是软状态的体现。

最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。

6.feign是声明式的web service客户端

7.单点登录

ticket:混淆性(UUID)、唯一性(用户名)、动态性(系统时间)

java对象转换成json串:ObjectMapper

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值