- 博客(116)
- 资源 (5)
- 收藏
- 关注
原创 时间复杂度和空间复杂度
时间复杂度和空间复杂度时间复杂度求解算法的时间复杂度的具体步骤是:找出算法中的基本语句;执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体。计算基本语句的执行次数的数量级;只需计算基本语句执行次数的数量级。这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可,可以忽略所有低次幂和最高次幂的系数。下面我来举一个简单例子: public static void main(String[] args) { int n = 10, a = 0;
2021-11-06 19:07:08 220
原创 分治 算法
分治算法基本思想把复杂问题分解成若干互相独立容易求解的子问题分治算法经典例子——-汉诺塔汉诺塔问题:如图有A(原柱)、B(借力柱)、C(目标柱)三个柱子,要求把A(原柱)上的圆盘从下面开始按大小顺序重新摆放到C(目标柱)上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。当A(原柱)上有两个盘子时,我们先把上面的小圆盘移动到B(借力柱),再把大圆盘移动到C(目标柱),最后把B(借力柱)上的圆盘移动到C(目标柱)就完成了。当A的圆盘上越多时,问题就越难解决,我们可以借助分治法来
2021-11-03 00:27:47 267
原创 二分查找算法
二分查找算法前提:有序数组首先确定整个查找区间的中间位置 mid = strat+(end-strat)/2用待查关键字key值与中间位置的关键字值进行比较;若相等,则查找成功若大于,则在后(右)半个区域继续进行折半查找若小于,则在前(左)半个区域继续进行折半查找重复上述步骤。方式一:非递归 public static int search(int key, int[] arr) { int start = 0; int end = arr.len
2021-11-02 23:55:14 220
原创 CAS原理
CAS原理CAS(compare and swap:比较和交换):是一种乐观的自旋锁。工作原理 举例:A=A+1从主存中读取A值,保存(A副本)到线程1的工作内存中。然后计算(A副本)+1后变成B值,最后再把B值写回到主存中。CAS的核心是在将B值写入到主存之前,要比较(A副本)和A值是否相同,如果不相同证明此时A值已经被其他线程改变,重新将A值赋给(A副本),并重新计算得到B,如果相同,则将B值写回到主存中。CAS其实就是实现一种乐观的自旋锁,相较于synchronize的悲观锁
2021-10-30 21:00:18 213
原创 ThreadLocal
ThreadLocalThreadLocal:线程变量,ThreadLocal为变量在每个线程中都创建了一个副本,该变量是当前线程独有的变量。对其他线程而言是隔离的。既然每个 Thread 有自己的实例副本,且其它 Thread 不可访问,那就不存在多线程间共享的问题。ThreadLocal 变量通常被private static修饰。当一个线程结束时,它所使用的所有 ThreadLocal 相对的实例副本都可被回收。Thread、 ThreadLocalMap及ThreadLocal 三者之
2021-10-28 23:58:22 104
原创 序列化和反序列化
序列化和反序列化序列化:将对象变成二进制保存在文件或者数据库中。反序列化:将文件中或数据库中的二进制文件变成一个对象。对象序列化的两种用途:**对象持久化:**把对象的字节序列永久地保存到硬盘上。**网络传输对象:**数据是以二进制序列的形式在网络上进行传输的。所以发送方需要把对象转换成字节序列,才能在网络上传送;接收方 则需要把字节序列再恢复成对象。举例:Web 服务器中的 Session 会话对象,当有10万用户并发访问,就有可能出现10万个 Session 对象,显然这种情况内
2021-10-27 00:12:17 902
原创 Eclipse快捷键
Eclipse快捷键查找与替换Ctrl + F 在当前文件进行文本查找与替换 (必备)Ctrl+H快捷键打开搜索框Ctrl+K 参照选中的Word快速定位到下一个Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)ctrl+shift+R查找目标文件代码快速生成
2021-10-25 07:26:14 339
原创 idea快捷键
idea快捷键查找与替换Ctrl + F 在当前文件进行文本查找 (必备)Ctrl + R 在当前文件进行文本替换 (必备)Ctrl + Shift + F 根据输入内容查找整个项目 或 指定目录内文件 (必备)Ctrl + Shift + R 根据输入内容替换对应内容,范围为整个项目 或 指定目录内文件 (必备)连按两次Shift 弹出 Search Everywhere 弹出层代码快速生成Alt + Enter IntelliJ IDEA 根据光标所在问题,提供快速修复选择,光标放在的位
2021-10-25 07:24:37 727 1
原创 集合常用方法
集合常用方法Collection接口的常用方法:add(T t) //添加指定元素 remove(T t) //删除指定元素 contains(T t) //是否包含某元素size() //获得元素的个数 toArray()方法将集合转换为Object数组toArray(T[] a)方法将集合转换为相应类型的数组iterator() //获得迭代器(Iterator类型),一般用于遍历 isEmpty() //集合是否为空 以下演示对Collection的操作方法 Co
2021-10-25 07:23:34 239
原创 线程安全问题
线程安全问题能用图的地方尽量不废话,先来看一张图:上图描述了一个多线程执行场景。线程 A 和线程 B 分别对主内存的变量进行读写操作。其中主内存中的变量为共享变量,多个线程间共享。但是线程不能直接读写主内存的共享变量,每个线程都有自己的工作内存,线程需要读写主内存的共享变量时需要先将该变量拷贝一份副本到自己的工作内存,然后在自己的工作内存中对该变量副本进行所有操作,线程工作内存对变量副本完成操作之后需要将结果同步至主内存。 我们在操作共享数据的时候,可能会出现线程安全问题。例子:线程A,B同时对
2021-10-25 07:20:58 241
原创 Java内存模型(原子性、可见性、有序性)
Java内存模型(原子性、可见性、有序性)原子性:原子性操作指相应的操作是单一不可分割的操作。同一时刻只能有一个线程来对它进行操作。简而言之,在整个操作过程中不会被线程调度器中断的操作,都可认为是原子性。在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作。在多线程环境中,非原子操作可能会受其他线程的干扰。举例:请分析以下哪些操作是原子性操作: x = 10; //语句1 y = x; //语句2语句1是原子性操作:语句1是直接将数值10
2021-10-24 11:40:34 2721
原创 synchronized与volatile
synchronized与volatilesynchronized:同步(synchronization)就是指一个线程访问数据时,其它线程不得对同一个数据进行访问,即同一时刻只能有一个线程访问该数据,当这一线程访问结束时其它线程才能对这它进行访问。可见性synchronization的两条规定:线程解锁前,必须把共享变量的最新值刷新到主内存线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值。原子性:由于synchronized能够保证
2021-10-24 11:39:27 293
原创 Thread的常用方法
Thread的常用方法方法说明yield()释放当前cpu的执行权。不会释放锁join()将某个线程插入到当前线程,使当前线程进入阻塞状态,直到插入的线程执行完,当前线程才结束阻塞状态。sleep()使当前线程进入阻塞状态,阻塞指定的毫秒数。 不会释放锁interrupt()中断线程。只能中断阻塞过程中的线程而不能中断正在运行过程中的线程。如sleep();wait()使当前线程进入阻塞状态,并释放同步锁notify()唤醒一个wait线程。
2021-10-24 11:33:47 112
原创 Java 线程池
线程池线程池的真正实现类是ThreadPoolExecutor。其构造方法有几个重要的参数:corePoolSize:核心线程数。默认情况下,核心线程会一直存活,但是当将allowCoreThreadTimeout设置为true时,核心线程也会超时回收。maximumPoolSize:线程池所能容纳的最大线程数。当活跃线程数达到该数值后,后续的新任务将会阻塞。keepAliveTime:线程闲置超时时长。如果超过该时长,非核心线程就会被回收。如果将allowCoreThreadTimeout设置为
2021-10-24 11:24:14 330
原创 创建多线程的方式
创建多线程的方式继承 Thread类实现 Runable接口实现 Callable接口线程池继承 Thread类创建Thread的子类,重写run()方法,然后启动Thread类public class Test { public static void main(String[] args) {// 第二步:创建Thread子类的对象,通过对象调用start方法(启动当前线程)。 new MyThread().start();//再启动一个多线程,要重新创建一
2021-10-24 11:14:50 85
原创 进程与线程
进程与线程线程:线程是一条执行路径,是程序执行时的最小单位。进程:进程是一个独立的运行环境,它可以看作一个程序或一个应用。进程和线程的关系:一个程序就是一个进程,而一个程序中的多个任务则被称为线程。进程是表示资源分配的基本单位。一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是程序执行时的最小单位。同一进程的所有线程共享该进程的所有资源。即同一个进程中的多个线程共享Java虚拟机的堆和方法区每个线程拥有自己的私有内存:Java虚拟机中的虚拟机栈,本地方法栈,程序计数
2021-10-24 11:08:48 2115
原创 串行和并行和并发
串行和并行和并发串行:代码从上而下按照固定的顺序执行,只有上一件事情执行完毕,才能执行下一件事。并发:并发的实质是一个CPU(也可以多个CPU) 在多个线程之间多路复用,以提高cup的利用率。通俗点讲,并发就是多个线程之间要竞争CPU的执行权,CPU要在多个线程之间来回切换(CPU与线程的关系:一对多)。并行:在同一时刻多个线程,在不同CPU(多核)上同时执行(CPU与线程的关系:一对一)。...
2021-10-24 11:05:53 492
原创 java IO流
IO流概念流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出IO流的分类按流的流向不同分为:输入流,输出流输入流:从别的地方获取资源 输入到 我们的程序中(只读)输出流:从我们的程序中 输出到 别的地方(只写)。按流的数据单位可以分为:字节流,字符流字节流:以字节为单位读写数据,当
2021-10-24 10:20:28 71
原创 idea快捷键
idea快捷键查找与替换Ctrl + F 在当前文件进行文本查找 (必备)Ctrl + R 在当前文件进行文本替换 (必备)Ctrl + Shift + F 根据输入内容查找整个项目 或 指定目录内文件 (必备)Ctrl + Shift + R 根据输入内容替换对应内容,范围为整个项目 或 指定目录内文件 (必备)连按两次Shift 弹出 Search Everywhere 弹出层代码快速生成Alt + Enter IntelliJ IDEA 根据光标所在问题,提供快速修复选择,光标放在的位
2021-10-24 10:17:02 59
原创 BIO和NIO
BIO和NIOJava 中的 BIO、NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装。程序员在使用这些 API 的时候,不需要关心操作系统层面的知识,也不需要根据不同操作系统编写不同的代码。只需要使用Java的API就可以了。BIO同步阻塞I/O模式:因为socket.accept()、 socket.read()、 socket.write() 是同步阻塞的。举例:当服务器用read去客户端的的数据时,是无法预知对方是否已经发送数据的。因此在收到数据之前,当前线程会
2021-10-24 00:18:53 2666
原创 LinkedHashSet
LinkedHashSet基于LinkedHashMap实现。用LinkedHashMap作为数据存储,保证了元素迭代的顺序,即插入顺序。继承 HashSet,其内部只定义spliterator()方法。可以直接调用父类HashSet的方法。LinkedHashSet只能实现插入顺序,不能实现访问顺序。源码分析LinkedHashSet继承HashSetpublic class LinkedHashSet<E> extends HashSet<E> i
2021-10-23 23:44:44 192
原创 HashSet
HashSet用HashMap作为数据存储,所有元素都存放在HashMap的key上面,定义一个虚拟的 Object 对象PRESENT 作为 HashMap 的 value 。HashMap最多只允许一个key为null,所以HashSet的元素可以为 NULL。HashMap无序,线程不安全,所以HashSet也是无序,线程不安全的。源码分析属性 private transient HashMap<E,Object> map; private static fi
2021-10-23 23:41:20 146
原创 LinkedHashMap
LinkedHashMapLinkedHashMap继承HashMap,其结构与HashMap相似它保证了元素迭代的顺序。该迭代顺序可以是插入顺序或者是访问顺序。我们知道HashMap有一个问题,就是它的遍历顺序是不确定的。但是有些场景,我们需要一个有序的Map。为解决这一问题,LinkedHashMap诞生了。它通过维护一个运行于所有条目的双向链表,虽然增加了时间和空间上的开销,但是保证了元素迭代的顺序。该迭代顺序可以是插入顺序或者是访问顺序。源码分析LinkedHashMap继承HashM
2021-10-23 23:36:44 1078
原创 HashMap
HashMap底层是数组+链表+红黑树它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。HashMapHashMap的key不能重复,只允许一个为null。value可以重复,允许多个null。HashMap非线程安全,如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。下面我们一起来分析源码属性
2021-10-23 23:33:48 176
原创 LinkedList
LinkedList底层是双向循环链表,在此链表上每一个数据节点都由三部分组成:前指针(指向它前一个元素),数据,后指针(指向它后一个元素)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。查询效率低(无法按照索引获得元素,因此查询效率不高),增删效率高(只需要挪动对应的指针)。没有固定容量,不需要扩容;需要更多的内存,每一个数据节点除了存放数据,还要存放它的前指针,和后指针。下面我们来分析LinkedList的源码:属性 transient int size = 0;//
2021-10-23 23:29:01 150
原创 ArrayList
ArrayList底层是Object数组,是一个动态数组,其容量能自动增长。是线程不安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。查询速度快(底层是数组可按照索引获得元素),增删速度慢(添加、删除时该元素后面的所有元素都要移动,所以添加/删除数据效率不高)。下面我们来分析ArrayList的源
2021-10-23 23:19:07 69
原创 Java 循环
Java 循环while循环while(循环条件) // 循环条件,条件为真进入{ 循环操作语句;}do-while循环do-while循环,至少循环一次do{ 循环操作;}while(循环条件); // 循环条件,条件为真继续循环三、for循环一般for循环for(表达式1;表达式2;表达式3)//其中,表示式皆可以省略,但“;”不可省略.{ 语句;}遍历数组 /* 建立一个数组 */ int[] integers = {1,
2021-10-23 21:50:28 186
原创 循环删除集合元素的那些坑
循环删除集合元素的那些坑1、for循环遍历listfor(int i=0;i<list.size();i++){ if(list.get(i).equals("del")) list.remove(i);}这种方式的问题在于,删除某个元素后,list的大小发生了变化,而你的索引也在变化,**所以会导致你在遍历的时候漏掉某些元素。**比如当你删除第1个元素后,继续根据索引访问第2个元素时,因为删除的关系后面的元素都往前移动了一位,所以实际访问的是第3个元素。2、增强for循环f
2021-10-23 21:40:36 310
原创 Iterator迭代器
Iterator迭代器Iterator接口定义了以下四种方法。方法作用boolean hasNext()如果集合还没遍历完就返回true。Object next()返回集合里的下一个元素。void remove()删除集合里上一次next方法返回的元素。void forEachRemaining(Consumer action)这是java8新增的默认方法,可用Lambda表达式遍历数组。一、使用迭代器遍历元素时不能不能通过Collection接口中的
2021-10-23 21:29:41 74
原创 Java自动和强制类型转换
Java自动和强制类型转换自动类型转换可以直接将一个小的数据类型直接赋值给大的数据类型。(自动类型转换) int a=100,b; byte c=100,d; b=c;//自动类型转换,小的数据类型可以直接赋值给大的数据类型// d=a;//报错,一个大的数据类型直接赋值给小的数据类型,不能直接转换强制类型转换不能(直接)把一个大的数据类型直接赋值给小的数据类型 。比如int32位,byte8位。byte存不下32位,最大只能存8位,所以
2021-10-23 13:54:15 159
原创 switch
switchswitch:从匹配到的case起,一直执行完。如果没匹配到case,则执行default。如果遇到break,退出switch 。举例public class demo { public static void main(String[] args) { fun1("a");//遇到break,退出switch System.out.println("=================="); fun2("a");//从匹配到的ca
2021-10-22 00:08:11 119
原创 break与continue
break与continue1、break:跳出一个循环体。2、continue:跳过本次循环中剩下尚未执行的语句,立即进入下一次循环。案例分析案例一public class Test { public static void main(String[] args) { for(int i=0; i<12; i++){ if(i==5){ break; } Syst
2021-10-21 23:45:03 67
原创 关键字final
关键字final数据声明数据为常量,可以是编译时常量,也可以是在运⾏时被初始化后不能被改变的常量。对于基本类型,final 使数值不变;对于引⽤类型,final 使引⽤不变,也就不能引⽤其它对象,但是被引⽤的对象本身是可以修改的。final int x = 1;// x = 2; // cannot assign value to final variable 'x'final A y = new A();y.a = 1;⽅法声明⽅法不能被⼦类重写。private
2021-10-21 22:03:31 51
原创 关键字static
关键字static1. 静态变量静态变量:⼜称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接 通过类名来访问它。静态变量在内存中只存在⼀份。实例变量:每创建⼀个实例就会产⽣⼀个实例变量,它与该实例同⽣共死。public class A { private int x; // 实例变量 private static int y; // 静态变量}2. 静态⽅法静态⽅法在类加载的时候就存在了,它不依赖于任何实例。所以静态⽅法必须有实现,也就是说它不能 是抽象⽅法。
2021-10-21 22:00:02 72
原创 类的初始化顺序
类的初始化顺序将一个类加载到Java虚拟机中需要经历三个阶段:加载->链接(验证、准备,解析)->初始化。加载:这是由类加载器(ClassLoader)执行的。通过一个类的全限定名来获取其定义的二进制字节流(Class字节码),将这个字节流所代表的静态存储结构转化为方法区的运行时数据接口,根据字节码在java堆中生成一个代表这个类的java.lang.Class对象。链接:2.1.验证:验证Class文件中的字节流包含的信息是否符合当前虚拟机的要求。2.2.准备:为静态域分配存储空间
2021-10-21 21:52:00 1979
原创 接口和抽象类
接口和抽象类:具体类——抽象类——接口:越来越抽象,内部实现的东西越来越少抽象类抽象类为复用而生:专门作为基类来使用,也具有解耦的功能。抽象类是未完全实现逻辑的类(可以有字段和和具体方法,他们代表了 “具体逻辑”)抽象类封装**的是确定的,开放的是不确定的**,推迟到合适的子类中去实现。抽象类和抽象⽅法都使⽤ abstract 关键字进⾏声明。如果⼀个类中包含抽象⽅法,那么这个类必须声明为抽象类。抽象类和普通类最⼤的区别是,抽象类不能被实例化,只能被继承。接⼝接口是完全未实现逻
2021-10-21 21:35:40 74
原创 关键字super
关键字super访问⽗类的构造函数:可以使⽤ super() 函数访问⽗类的构造函数,从⽽委托⽗类完成⼀些初始化的⼯作。应该注意到,⼦类⼀定会调⽤⽗类的构造函数来完成初始化⼯作,⼀般是调⽤⽗类的默认构造函数,如果⼦类需要调⽤⽗类其它构造函数,那么就可以使⽤ super() 函数。访问⽗类的成员:如果⼦类重写了⽗类的某个⽅法,可以通过使⽤ super 关键字来引⽤⽗类的⽅法实现。//public class SuperExample { protected int x; protected i
2021-10-21 21:33:52 63
原创 深拷贝和浅拷贝
深拷贝和浅拷贝cloneableclone() 是 Object 的 protected ⽅法,⼀个类不显式去重写 clone(),其它类就不能直接去调⽤该类实例的 clone() ⽅法。public class CloneExample { private int a; private int b; }CloneExample e1 = new CloneExample();// CloneExample e2 = e1.clone(); // 'clone()' has protecte
2021-10-21 21:30:23 248
原创 权限修饰符
权限修饰符private:(同一个类中使用)。在不同类中即使在外部创建对象,仍然不可以通过对象访问私有权限的成员。缺省(default):(同一个包中使用)。被default所修饰的成员、可以在同一package中的所有类访问到。protected:(同一个**包中或不同包的子类中**可以使用)。被protected所修饰的成员、可以在同一package中的所有类访问到。同时,可以在不同包下的子类中使用public:(同一个工程中使用)可以在任何类中都能被访问到。...
2021-10-21 21:28:59 98
原创 Java注解
注解什么是注解?Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。注解的用处生成文档。这是最常见的,也是java 最早提供的注解。常用的有@param @return 等跟踪代码依赖性,实现替代配置文件功能。比如Dagger 2 依赖注入,未来java 开发,将大量注解配置,具有很大用处;在编译时进行格式检查。如@override
2021-10-20 23:00:27 90
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人