
Java
文章平均质量分 68
梦否
【@】bug修复,程序代做
展开
-
Android插件化开发指南——基础之反射
文章目录1. 前言2. 反射2.1 获得代表类的Class对象2.1.1 getClass2.2.2 Class.forName2.2.3 类的class属性2.2.4 基本类型的TYPE属性2.2 获取类的成员2.2.1 构造函数2.2.2 普通方法2.2.3 静态方法2.2.4 私有非静态属性2.2.5 私有静态属性2.3 对泛型类的反射3. 后记1. 前言Java中最强大的技术:反射!为什么这么说,不妨再次来简单回忆一下Spring这个框架。 我们知道Spring 是目前主流的 Java原创 2021-11-12 21:28:54 · 1805 阅读 · 0 评论 -
【Java】两个线程循环打印1-10
有点类似于之前写过的Java实现生产者消费者模式,这里继续来巩固下。首先是使用synchronized方式来实现。public class Main { private static volatile int number = 0; private static final Object object = new Object(); // 对象锁 public static void main(String[] args) { new Thread(new原创 2021-09-15 09:19:43 · 1682 阅读 · 0 评论 -
Base64编码原理
这里仅修复原文中的图示,其余内容不做修改。这篇文章对Base64编码原理讲解的很好,原文链接:https://hello.blog.youkuaiyun.com/article/details/817347701. Base64的由来 目前Base64已经成为网络上常见的传输8bit字节代码的编码方式之一。在做支付系统时,系统之间的报文交互都需要使用Base64对明文进行转码,然后再进行签名或加密,之后再进行(或再次Base64)传输。那么,Base64到底起到什么作用呢? 在参数传输的过程中经常遇转载 2021-09-01 17:16:16 · 163 阅读 · 0 评论 -
528. 按权重随机选择
记录一道比较有意思的题,按权重随机选择,感觉在实际中会用到。1. 题目描述给定一个正整数数组 w ,其中 w[i] 代表下标 i 的权重(下标从 0 开始),请写一个函数 pickIndex ,它可以随机地获取下标 i,选取下标 i 的概率与 w[i] 成正比。例如,对于 w = [1, 3],挑选下标 0 的概率为 1 / (1 + 3) = 0.25 (即,25%),而选取下标 1 的概率为 3 / (1 + 3) = 0.75(即,75%)。也就是说,选取下标 i 的概率为 w[i] / su原创 2021-08-30 09:41:35 · 151 阅读 · 0 评论 -
不用for循环找最大值
1. 使用Jdk1.8中的流private static int getMax(int[] arr){ return Arrays.stream(arr).max().getAsInt();}2. 使用递归来代替for/** * 递归的从后往前找最大值,最大值记录在lastVal变量中 * @param arr 待求数组 * @param lastIndex 数组最后一个下标 * @param lastVal 数组最后一个元素 * @return */private stat原创 2021-08-29 20:11:04 · 582 阅读 · 0 评论 -
RESTful 规范
1. 基本概念 REST全称是Representational State Transfer,中文意思是表征性状态转移。指的是一组架构约束条件和原则。如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。如果后台开发遵守了REST风格便可称为RESTful。REST本身并没有创造新的技术,是一种软件架构风格,以更好地使用现有Web标准中的一些准则和约束。结构清晰、符合标准、易于理解、扩展方便。 RESTful架构是对MVC架构改进后所形成的一种架构,通过使用事先定义好的原创 2021-08-29 10:36:21 · 4438 阅读 · 0 评论 -
ReentrantLock源码分析
我们知道在Java中有两种经常见到的悲观锁,分别是:synchronized和ReentrantLock。下面简单的对两者进行一个区别对别:两者都是可重入锁;“可重入锁”即:自己可以再次获取到自己的内部锁。比如一个线程获得了对某个对象的锁,此时这个锁还没有被释放,当其再次想要获得这个对象的锁的时候,不用等待这个锁释放了后再去获取,而是直接可以获取到这个锁对象。如果不可重入锁,可能会导致死锁,因为同一个线程每次获取该对象的锁的时候,锁的计数器加1(当计数器的大小为0的时候,才可以获取锁),那么自己在还没有原创 2021-08-27 12:04:01 · 170 阅读 · 0 评论 -
剑指 Offer 68 - II. 二叉树的最近公共祖先
1. 题目描述给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]示例 1:输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1输出: 3解释: 节原创 2021-08-26 17:31:59 · 111 阅读 · 0 评论 -
多线程的LRU缓存
在之前的这篇LRU缓存Java实现中介绍了LRU缓存的简单实现。今天尝试来继续深入点。首先我们抽象接口,我的文件结构如下:为了面向非单一的固定类型,这里使用泛型来定义:public interface Cache<K, V> { V get(K key); void set(K key, V value); int size();}1. 单线程LUR缓存在单线程LUR缓存的设计中,保持和上篇的一致,即还是使用HashMap+双向链表来实现。另外为了测试比较原创 2021-08-26 11:50:14 · 926 阅读 · 0 评论 -
Atomic相关原子类
这些类都是使用非阻塞式的CAS操作实现的原子操作。相比于锁来实现原子操作,这些操作在性能上有很大的提高。由于原子性操作的类的原理大致都是相同的,这里以AtomicLong类来说明。JUC下有AtomicInteger、AtomicLong和AtomicBoolean等。其内部使用sun.misc.Unsafe类来实现。前面提到了在AtomicXX类中使用非阻塞式的CAS操作来实现的原子操作。这里首先来看下CAS操作:比如在AtomicLong类中就多次使用了unsafe实例的compareAndS原创 2021-08-20 17:46:47 · 154 阅读 · 0 评论 -
公平锁实现
为了实现公平锁,我们可以看下ReentrantLock类中的源码是如何写的。因为在ReentrantLock类中默认是非公平锁,但是我们可以指定为公平锁。那么,可以直接提取一个公平锁的封装出来:FairLock.javapublic class FairLock implements Lock { private final Sync sync = new Sync(); @Override public void lock() { sync.acquire原创 2021-08-20 15:59:12 · 468 阅读 · 0 评论 -
ThreadLocal工作原理
在使用Hanlder消息机制的时候,曾简单阅读过Handler的部分源码,我们知道其消息机制中有如下几个重要部分:Handler;Looper;MessageQueue;Message;ThreadLocal;对于ThreadLocal这里来进行再一次的源码分析和理解。在使用Handler消息机制中,我们在每个线程中可以很轻松的得到Looper对象,比如Looper.myLooper();(当然,需要是你之前Looper.prepare()过)。我们知道每一个线程中都有一个与之关联的Loo原创 2021-08-16 17:22:07 · 200 阅读 · 0 评论 -
Java静态成员变量将在构造函数调用完毕后,才赋值
做题遇到这样一个题:class Person { public String name = "Person"; public Person() { sayName(); } public void sayName() { System.out.println(name); }}class Student extends Person { public String name = "Student"; public原创 2021-08-19 21:29:36 · 676 阅读 · 0 评论 -
SpringBoot项目高并发问题
在SpringBoot项目中通常我们没有处理并发问题,但是使用项目本身还是支持一定的并发量,因为在SpringBoot中内嵌Tomcat容器,而Tomcat在spring-configuration-metadata.json文件中设置了关于并发的默认配置:{ "name": "server.tomcat.max-connections", "description": "“服务器在任何给定时间接受和处理的最大连接数。", "defaultValue": 8192},{ "name"原创 2021-08-18 11:56:30 · 13920 阅读 · 0 评论 -
Java实现生产者消费者模式
大致百度了下发现其实实现方式还挺多的。1. synchronized + Object对象的wait()和notifyAll()我的项目包结构如下:生产者接口Producer.javapublic interface Producer { void produce() throws InterruptedException;}消费者接口Consumer.javapublic interface Consumer { void consume() throws Interru原创 2021-08-16 22:31:59 · 344 阅读 · 0 评论 -
什么是协程
在上篇:子线程使用消息机制更新UI将到AsyncTask现在已经被废弃的时候提到,在Android中使用多线程建议使用ThreadPoolExecutor线程池,或者使用JUC其他类,以及最后的协程方式。对于ThreadPoolExecutor等在线程池ThreadPoolExecutor已经介绍过了,这里不再介绍。协程,英文Coroutines,是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。最重要的是,协程不是被操作系统内核所管理,而完全是由程序所控制(原创 2021-07-29 15:41:02 · 168 阅读 · 0 评论 -
线程池ThreadPoolExecutor
文章目录1. 线程的创建1.1 `FutureTask`和`Callable`实现1.2 线程池`Executor`1.2.1 `ThreadPoolExecutor`介绍1.2.2 `ThreadPoolExecutor`简单使用案例1. 线程的创建在Java中一共有四种创建线程的方式,分别是:继承Thread类,然后new Thread().start();实现Runnable接口,然后new Thread(new Runnable()).start();使用Callable和Future创原创 2021-07-27 17:14:45 · 282 阅读 · 0 评论 -
强、软、弱、虚四种类型引用
1. 强引用把一个对象赋值给一个引用变量,这个引用变量就是一个强引用,是Java中默认的引用方式。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制给回收掉的,即使该对象以后永远都不会被用到也不会被JVM回收掉。因此,强引用是造成Java内存泄漏的主要原因之一。对于一个普通的对象,如果超出对象的生命周期范围,或者显示的将相应强引用赋值为null,一般就认为可以被当作垃圾收集了。如:Object object =new Object(); // 强引用2. 软引用使用jav原创 2021-07-25 10:00:58 · 1405 阅读 · 0 评论 -
Java父类中调用子类的方法
接口和继承public interface In { void doSomething();}父类:public class T{ private In in; public void setIn(In in){ this.in = in; } // 需要子类重写的普通方法 protected void layoutChildren() { } public void Hello(){ // 用子类.原创 2021-07-23 16:44:37 · 7766 阅读 · 0 评论 -
字符编码中ASCII、Unicode和UTF-8的区别
最早只有127个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。因此,Un转载 2021-07-19 20:17:40 · 254 阅读 · 0 评论 -
wait()、join()、sleep()、yield() 和 interrupt()方法
Object的wait方法:wait指线程处于进入阻塞状态,不占用任何资源,不增加时间限制。Thread的sleep方法: sleep指线程被调用时,占着CPU不工作,其他线程无法进入,会增加时间限制。Thread的yield方法:yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!..原创 2021-07-19 15:26:04 · 865 阅读 · 0 评论 -
synchronized 关键字的同步语句块
比如单例模式:public class Singleton { private Singleton(){} private volatile static Singleton uniqueSingleton; public static Singleton getUniqueSingleton(){ if(uniqueSingleton == null){ synchronized(Singleton.class){原创 2021-07-18 12:03:07 · 176 阅读 · 0 评论 -
JVM虚拟机知识点浅析总结
文章目录0. 方法指令1. 类加载器1.1 类加载过程1.1.1. 加载1.1.2. 链接1.1.3. 初始化1.2 类加载时机1.3 类加载器1.4 双亲委派机制1.5 自定义类加载器2. 类加载机制3. `Java`内存模型4. Java 内存回收机制4.1 对象存活判断4.2 新生代和老年代的区别5. 垃圾收集器JVM是Java Virtual Machine的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机。使用java -version可以查看当前自己安装的是什么虚拟机:Ja原创 2021-07-17 16:22:11 · 285 阅读 · 0 评论 -
字符串的排列Java
刷题记录第22题,上一题:数据流中的中位数,本题地址:字符串的排列。题目描述:输入一个字符串,打印出该字符串中字符的所有排列。你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。示例:输入:s = "abc"输出:["abc","acb","bac","bca","cab","cba"]限制:1 <= s 的长度 <= 8这道题是一道典型的回溯法问题。在之前的八皇后问题的博客中也采用了回溯的思想。在算法小抄的一书中说到:解决一个回溯问题,实际上就是一个决策树的遍历原创 2021-07-12 16:33:16 · 237 阅读 · 0 评论 -
HashSet装入ArrayList对象,去重
比如:HashSet<String> strings = new HashSet<>(list); // List<String> list;对应的构造函数:// HashSet extends AbstractSet// AbstractSet extends AbstractCollection// HashMap<E,Object> map;public HashSet(Collection<? extends E> c) {原创 2021-07-12 16:29:57 · 865 阅读 · 0 评论 -
对称加密和非对称加密
1. 对称加密加密和解密使用同一个秘钥,所以叫做对称加密。常见的对称加密算法:DES,AES等。其过程可以描述为:加密:原文 + 密匙 = 密文解密:密文 - 密匙 = 原文对称加密通常使用的是相对较小的密钥,一般小于256 bit。如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性,也要照顾到效率,是一个trade-off。面临的最大的问题为:秘钥的分发。就是说,解密方如何获得加密方的秘钥呢?在发送密钥的过程中,密钥有很大的风原创 2021-07-12 10:22:54 · 2972 阅读 · 0 评论 -
PriorityQueue的解读
PriorityQueue继承自抽象类AbstractQueue,默认初始容量设置为11,存储的容器在底部为对象数组Object[],如下:public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serializable {transient Object[] queue;我们一般在使用的时候,会在构造函数初始化的时候传入比较器,比如:new PriorityQueue&l原创 2021-07-11 15:31:34 · 298 阅读 · 0 评论 -
synchronized 和 lock 的区别
1. 知识复习1.1 线程与进程进程是资源分配的基本单位。线程是独立调度的基本单位。进程和线程的关系:(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。(3)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。(4)处理机分给线程,即真正在处理机上运行的是线程。(5)线程是指进程内的一个执行单元,也是进程内的可调度实体。线程与进程的区别:(1)调度:线程作为调度和分配的基本原创 2021-07-10 21:03:53 · 167 阅读 · 1 评论 -
可重入锁 & 自旋锁
1. 可重入锁可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。synchronized和ReentrantLock都是可重入的。ReentrantLock 和 synchronized 不一样,需要手动释放锁,所以使用 ReentrantLock的时候一定要手动释放锁,并且加锁次数和释放次数要一样可重入锁的一个好处是可一定程度避免死锁。public synchronized void mehtodA(){ mehtodB();} public synchronized voi原创 2021-07-10 20:27:18 · 1080 阅读 · 0 评论 -
ReadWriteLock读写锁
对应的Java8的文档地址:hereReadWriteLock是一个接口,已知的实现类只有一个,即:ReentrantReadWriteLock。这个接口提供了一组锁,一个用于只读操作,一个用于写入。 read lock可以由多个阅读器线程同时进行。 write lock是独占的。其方法只有两个:下面给出一个读写锁的典型用法:class MyList<T> implements List<T>{ private List<T> list = new A原创 2021-07-10 20:09:25 · 367 阅读 · 0 评论 -
乐观锁和悲观锁
在多线程环境下,由于需要保证数据的准确性,故而产生了相关的并发控制手段,比如这里的乐观锁和悲观锁。乐观锁和悲观锁,是一种编程思想。1. 悲观锁悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁。也就是说只有自己使用完毕了,才释放锁给其他线程。这样其他线程想操作这个数据拿不到锁只能阻塞了。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁,读锁,写锁等,都是在做操作之前先上锁。在Java中synch原创 2021-07-10 17:44:04 · 177 阅读 · 0 评论 -
volatile的作用总结与理解
文章目录1. 前言2. `volatile`的作用:2.1 使用`volatile`来解决多核`CPU`高速缓存导致的变量不同步问题;2.2 `volatile` 还可以解决指令重排序问题2.3 `volatile`不能保证操作的原子性1. 前言volatile这个关键字比较重要,尤其是在看多线程的时候,会经常出现。那么就来看下这个关键字到底有什么用。volatile这个关键字的引入是为了线程安全,但是volatile不保证线程安全。在多处理器的系统中(或者单处理器多核的系统),每个处理器(每个核原创 2021-07-06 21:42:52 · 6098 阅读 · 3 评论 -
LinkedList的一些知识总结
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializablepublic abstract class AbstractSequentialList<E> extends AbstractList<E> LinkedList :原创 2021-07-06 18:32:34 · 182 阅读 · 0 评论 -
ArrayList的一些知识点总结
泛型类,继承自AbstractList,实现了List、RandomAccess, Cloneable, java.io.Serializable接口。所以ArrayList 是支持快速访问、复制、序列化的。也就是说,在ArrayList的父类AbstractList中实现了List接口,其超级父类中实现了Collection接口。记住一点:List和Collection均是接口。ArrayList 底层是基于对象数组来实现的。private static final int DEFAULT_.原创 2021-07-06 16:35:42 · 325 阅读 · 0 评论 -
HashMap的一些常见问题
1. HashMap 不是线程安全的,那如果多线程下,它是如何处理的?并且什么 情况下会发生线程不安全的情况?HashMap 不是线程安全的,如果多个线程同时对同一个 HashMap 更改数据的话,会导致数据不一致或者数据污染。如果出现线程不安全的操作时,HashMap会尽可能的抛出 ConcurrentModificationException 防止数据异常。当我们在对一个 HashMap 进行遍历时,在遍历期间,我们是不能对 HashMap 进行添加,删除等更改数据的操作的,否则也会抛出 Conc转载 2021-07-05 20:24:30 · 1071 阅读 · 0 评论 -
HashMap 和 HashTable 的区别?
1. 容器整体结构:HashMap的key和value都允许为null,HashMap遇到key为null的时候,调用 putForNullKey 方法进行处理,而对 value 没有处理。Hashtable 的 key 和 value 都不允许为 null。Hashtable 遇到 null,直接返回 NullPointerException。2. 容量设定与扩容机制:HashMap 默认初始化容量为 16,并且容器容量一定是 2 的 n 次方,扩容时(当存储的元素个数 size = ca转载 2021-07-05 20:06:52 · 142 阅读 · 0 评论 -
为什么重写了 equals 方法,还要重写 hashCode 方法?
往HashMap添加元素的时候,需要先定位到在数组的位置(hashCode方法)。如果只重写了 equals 方法,两个对象 equals 返回了true,集合是不允许出现重复元素的,只能插入一个。此时如果没有重写 hashCode 方法,那么就无法定位到同一个位置,集合还是会插入元素。这样集合中就出现了重复元素了。那么重写的equals方法就没有意义了。如果重写了hashcode方法,确保两个对象都能够定位到相同的位置,那么就可以遍历这条单向链表,使用equals方法判断两个对象是否相同,如果相同,原创 2021-07-02 17:17:15 · 190 阅读 · 0 评论 -
String、StringBuffer和StringBuilder的区别?
String为包装类,在Java中包装类均使用final关键字修饰,表示这个类不能被继承。在String类中使用字符数组来存储数据。String 拼接字符串时每次都会创建新的对象,适合少量拼接使用,速度最慢StringBuffer 线程安全,适合多线程使用,比String快StringBuilder 线程不安全,适合单线程使用,速度最快这三个类都实现了java.io.Serializable, CharSequence接口,且都为final修饰的类。对于StringBuffer和StringBui原创 2021-07-02 17:06:24 · 104 阅读 · 0 评论 -
Java接口中的成员变量是public static final?
我们可以在接口中定义一些所需要的属性,比如:interface Myinterface{ int a = 0;}System.out.println(Myinterface.a);如果我们操作这个变量a,那么:这里报错也就证实了在接口中定义的属性为final类型,且注意到我们直接可以通过.运算符得到值,故而这里的类型推断为public static final。那么,为什么Java接口中的成员变量是public static final?假设不是static,因一个类可以实现多个接原创 2021-07-02 16:40:35 · 821 阅读 · 0 评论 -
HashMap排序问题 & 字符串出现次数的TopK问题
字符串出现次数的TopK问题即HashMap的排序问题。描述给定一个字符串数组,再给定整数k,请返回出现次数前k名的字符串和对应的次数。返回的答案应该按字符串出现频率由高到低排序。如果不同的字符串有相同出现频率,按字典序排序。对于两个字符串,大小关系取决于两个字符串从左到右第一个不同字符的 ASCII 值的大小关系。比如"ah1x"小于"ahb",“231”<”32“字符仅包含数字和字母[要求]如果字符串数组长度为N,时间复杂度请达到O(N \log K)O(NlogK)示例1输原创 2021-06-24 09:26:36 · 370 阅读 · 0 评论