java
藤原豆腐店-
准备迁移博客,新博客地址:https://www.jianshu.com/u/16102e967c0f
展开
-
RocketMQ消息消费方式 推拉模式
RocketMQ消息消费本质上是基于的拉(pull)模式,consumer主动向消息服务器broker拉取消息。consumer被分为2类:MQPullConsumer和MQPushConsumer,其实本质都是拉模式(pull),即consumer轮询从broker拉取消息。 区别:MQPushConsumer方式,consumer把轮询过程封装了,并注册MessageListener监...原创 2019-04-14 11:42:40 · 8523 阅读 · 2 评论 -
今日头条后台开发岗(Java)实习面试
首先上来是自我介绍。第一题:算法题。给定一个数组和一个目标结果,返回数组中两个数的和等于目标结果的索引的数组,要考虑数组中的重复元素。比如,给一个数组{2,-1,0,2,18,30,20},target=20。那返回的结果集应该为[2,6],[0,4],[3,4]。这道题刷LeetCode的时候做过类似的,只不过那道题没有重复元素。回答:思路是建一个map,将数组的值存为key,索...原创 2020-07-15 10:36:45 · 457 阅读 · 0 评论 -
Java内存模型 内存管理机制理解
JVM主要将内存分为栈和堆。如果细分的话有程序计数器,虚拟机栈,本地方法栈、堆、方法区。如图所示 程序计数器由于在JVM中,多线程是通过线程轮流切换来获得CPU执行时间的,在任一具体时刻,一个CPU的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都需要有自己独立的程序计数器,并且不能互相被干扰,否则就会影响到程序...原创 2019-02-26 17:20:35 · 310 阅读 · 0 评论 -
二叉树深度优先遍历(递归、非递归)、广度优先遍历、构建二叉树
public class BinaryTree { static class TreeNode{ int value; TreeNode left; TreeNode right; public TreeNode(int value){ this.value = value; } ...原创 2019-02-26 16:56:51 · 3208 阅读 · 3 评论 -
Java多线程学习(十二)并行递归算法学习
并行循环如果一个循环中的每次迭代都是独立的,彼此没有影响,那可以将一个顺序的循环变成一个并行的循环。//顺序执行 void processSequentially(List<Element> elements){ for (Element e:elements) { process(e); } } ...原创 2019-02-26 16:57:41 · 4411 阅读 · 0 评论 -
Java多线程学习(十一)中断机制interrupt学习
在实际应用中,如果想停掉某个线程,那么可以调用线程的stop()方法或者suspend()方法来强制性的停止某个线程。但是这种方法是很粗暴的,它是强制性的停止线程,这样可能会导致线程之前工作的数据丢失,所以Java已经摒弃了这些强制终止的方法。取而代之的是一种中断机制,interrupt()方法。在JVM中每个线程都有一个boolean类型的线程是否中断的标志,调用线程中断的方法只是将这个标志...原创 2019-02-26 16:57:51 · 372 阅读 · 0 评论 -
HashMap底层实现原理 扩容机制
实现原理:HashMap本质是一个一定长度的数组,数组中存放的是链表。它是一个Entry类型的数组,Entry的源码:static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; final int hash; ...原创 2019-02-26 16:58:25 · 23304 阅读 · 16 评论 -
LinkedList源码阅读分析
LinkedList是一个双向链表,有一个previous指向前一个节点,一个next指向后一个节点。 prev data next LinkedList实现了多个接口:LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。 LinkedList 实现 List 接口,能对它...原创 2019-02-26 16:58:21 · 157 阅读 · 0 评论 -
ArrayList随机访问,动态扩容
随机访问:ArrayList是一个动态数组,实现了RandomAccess接口,支持随机访问,通过get(i)即可获得相应内存中存放的值。原因是因为ArrayList存放的内容在内存中是连续的,数组直接用[ ]访问,相当于直接操作内存地址,所以随机访问的效率较高。普通的for循环是随机访问的,所以遍历ArrayList使用普通for循环比增强for循环和迭代器的效率高。而LinkedL...原创 2019-02-26 16:58:15 · 3888 阅读 · 1 评论 -
Java多线程学习(十)CompletionService学习
CompletionService整合了Executor和BlockingQueue的功能。可以将多个Future任务添加到BlockingQueue的队列中,然后获取是可以调用take(阻塞)或poll(非阻塞)方法从队列中获取任务的执行结果。添加到队列中的任务时按照执行完成时间的顺序添加进去的,先完成的任务先添加到队列中,所以从队列中获取任务结果也一定是先获取到最先计算完成的。 E...原创 2019-02-26 16:57:56 · 225 阅读 · 0 评论 -
Java设计模式之 工厂模式解析
工厂模式一般用于当我们创建复杂对象时,通过简单的new来创建会比较麻烦,这时候我们就可以使用工厂模式来创建一个工厂类,我们只需向工厂类中传入需要创建的类的有关信息即可,工厂类中实现了创建对象的复杂细节。比如我们创建一个制造汽车的工厂类,我们传入不同的车型号,制造出不同的车。 简单工厂模式:创建一个工厂类,在类中通过传入的参数不同创建不同的实体类。有新需求时需要更改工厂类中的代码,违...原创 2019-02-26 16:59:26 · 1821 阅读 · 1 评论 -
Java多线程学习(五)同步容器与并发容器,ConcurrentHashmap,CopyOnWriteArrayList
同步容器:同步容器是将所有的方法都加了synchronized修饰,每个方法都要同步来执行,虽然保证了线程安全,但是因为线程获得的锁是整个对象的锁,所以降低了性能。比如说Vector这个容器,Vector就是加了synchronized修饰的ArrayList,ArrayList和LinkedList都不是线程安全的,如果要用线程安全的list,可以使用Vector,不过更好的方法是使用C...原创 2019-02-26 17:16:08 · 272 阅读 · 0 评论 -
Java设计模式之 建造者模式反思
应用场景:当创建一个复杂对象要牵扯到创建其他好几个对象时或者牵扯很多属性,也就是这个复杂对象的创建要通过一定的算法整合其他对象才能生成,这时候就可以使用建造者模式。官方说法:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。用户就只需要指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。stringBuilder这个类就是使用的建造者模式,其中的...原创 2019-02-26 16:58:47 · 270 阅读 · 0 评论 -
Java NIO学习
Java的普通IO是面向流的IO,从流中读取数据,将数据写入流中。是一个字节一个字节的读取和写入,而NIO是jdk1.4后推出的面向块的IO流,通过加入缓冲区和管道,以数据块为单位对数据进行IO。缓冲区Buffer:本质是一个由数组实现的容器,数据从文件或从其他地方读取首先需要装入到缓冲区中,写入也是先写入到缓冲区,而不是直接从Stream中读取或写入。管道Channel:数据传输...原创 2019-03-05 16:05:56 · 287 阅读 · 0 评论 -
GC可达性分析回收算法 解决循环引用问题 强引用弱引用
JVM有一个回收算法是引用计数算法,每当对象被引用一次,就+1,释放一个引用就-1,当垃圾回收时,引用计数为0的对象就会被GC掉。但这个方法有个问题,就是无法解决循环引用的问题。循环引用就是对象A引用了对象B,对象B引用了对象A,构成了一个引用环。彼此都没发挥什么作用,但却不会被GC。为了解决这个问题,就有了可达性分析回收算法。可达性分析:算法中定义了几个GC Root对象,这几个ro...原创 2019-03-05 16:06:01 · 4023 阅读 · 0 评论 -
终于搞懂了什么是二叉查找树,AVL树,B树,B+树,红黑树
二叉查找树:二叉查找树就是左结点小于根节点,右结点大于根节点的一种排序树,也叫二叉搜索树。也叫BST,英文Binary Sort Tree。二叉查找树比普通树查找更快,查找、插入、删除的时间复杂度为O(logN)。但是二叉查找树有一种极端的情况,就是会变成一种线性链表似的结构。此时时间复杂度就变味了O(N),为了解决这种情况,出现了二叉平衡树。 平衡二叉树:平衡二叉树全称平衡二...原创 2019-02-26 16:55:13 · 16475 阅读 · 1 评论 -
HashMap的死循环问题
HashMap在put操作时,如果达到了扩容条件,会触发resize操作,对map进行扩容。public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.len...原创 2019-03-20 18:34:25 · 617 阅读 · 0 评论 -
Java判断字符串是不是时间日期格式
引入jar包:import org.apache.commons.lang3.time.DateUtils; private static String[] parsePatterns = {"yyyy-MM-dd","yyyy年MM月dd日", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd"...原创 2019-03-06 10:31:39 · 17703 阅读 · 3 评论 -
Java中的ThreadLocal、ThreadLocalMap原理学习
public class ThreadLocalTest { public static void main(String[] args) { final ThreadLocal<Integer> local = new ThreadLocal<>(); local.set(10); Thread t = new T...原创 2019-03-06 10:26:47 · 1480 阅读 · 0 评论 -
Java反射中Class.forName()和ClassLoader.loadClass()的区别
一、Java类装载过程装载:通过累的全限定名获取二进制字节流,将二进制字节流转换成方法区中的运行时数据结构,在内存中生成Java.lang.class对象; 链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的; 校验:检查导入类或接口的二进制数据的正确性;(文件格式验证,元数据验证,字节码验证,符号引用验证) 准备:给类的静态变量分配并初始化存储空间...转载 2019-03-05 16:06:55 · 354 阅读 · 0 评论 -
new Hashmap时设置初始化容量多少合适
在阿里巴巴Java开发手册中,阿里工程师对于初始化hashmap的容量的建议是:刚看到这个建议,是非常懵的,为啥要这样设置?在jdk中,当我们new hashmap并且指定初始化容量capacity时,jdk会帮我们取第一个大于capacity的2次幂。具体的实现是:1.先把capacity - 12.进行多次无符号右移和或运算3.最后 + 1比如,我们...原创 2019-03-05 16:06:51 · 27795 阅读 · 2 评论 -
适配器模式在Java中的应用
Java中Array.asList()方法就是用的适配器模式,这个方法只是在原来的数组上包了一次list,实际上数据还是保存在数组中。如果对Array.asList()方法得到的list调用add,remove等操作,将抛出了UnsupportedOperationException。因为asList()方法返回的是Array的一个内部类,并不是正经的List类,它并没有实现List类的一...原创 2019-03-05 16:06:46 · 669 阅读 · 1 评论 -
局部变量、实例变量的线程安全性
局部变量是线程安全的。因为局部变量是声明在方法中的变量,方法是放在JVM内存中的方法区的,为方法分配内存的时候并不会为局部变量分配内存,只有在有线程在调用方法的时候才会为局部变量分配内存,并且局部变量是分配在栈上的,栈空间是线程私有的,所以,每当有线程执行方法,都会为其在栈上分配一个局部变量的空间。所以局部变量是属于线程的,是线程安全的。实例变量的线程安全要分两种情况来说。对于单例模式下对象的...原创 2019-03-05 16:06:37 · 854 阅读 · 0 评论 -
Java循环中创建多个对象是几个引用?以及是否线程安全
在循环中,通过User user = new User();这种方式创建的对象。每次创建的对象是不同的,但是引用是同一个,引用的生命周期是单次循环,下次循环会覆盖调上次的引用。比如这段代码: int minId = 0; while (true){ List<InvitationRel> invitationRelList...原创 2019-03-05 16:06:29 · 2151 阅读 · 0 评论 -
Java代码判断字符串中是否含有表情
最近在发微信公众号模版消息时遇到一个问题,如果用户的nickname中有表情,那么消息的字体颜色就会发生变化,像这样:这个问题应该是微信的问题,所以我们不能解决掉这个bug,只能等腾讯爸爸来修复。唯一能做的就是去除掉字符串中的表情,下面是具体代码。/** * 判断字符串中是否含有表情 * @param source * @return */ ...转载 2019-03-05 16:06:24 · 8221 阅读 · 0 评论 -
java8 sublist不可序列化问题
Java8中的arraylist的sublist的方法,返回的是一个sublist类型的视图。这个sublist类型是arraylist的一个内部类,不支持序列化,所以在转成json的时候会报错。视图的含义就是它虽然里面的元素数量变了,但是操作其中的元素实际上操作的还是原来list,并不是一份新的list。如果改变原有的list,那么sublist会抛出ConcurrentModifica...原创 2019-03-05 16:06:15 · 2274 阅读 · 0 评论 -
Java和C C++ 在内存分配方式上的不同
Java中,基本类型是直接存储值的,放在内存的栈中存储。存储在栈中的数据,需要有固定的大小和生命周期。因为栈中的内存分配方式是向下增长的,栈顶指针向下移动,就会分配内存(压栈);向上移动,就会释放内存(弹栈)。如果一直压栈,当栈内存不足时,就会发生栈溢出。所以Java中基本数据类型和对象的引用是存放在栈中的。并且基本数据类型的大小不会根据机器硬件架构的变化而变化,保证了固定大小。基本类型变量或者引...原创 2019-03-05 16:06:19 · 1336 阅读 · 0 评论 -
Java8新特性lambda stream 函数接口学习
Lambda表达式:格式为:expression = (variable) -> action含义就是将几个变量通过action代码中的逻辑,计算出结果返回给expression表达式。变量为一个时,可以不加括号。 List<Integer> list = Arrays.asList(1,2,5,8,7,4); Collection...原创 2019-03-05 16:06:05 · 355 阅读 · 0 评论 -
Java多线程学习(四)同步容器的复合操作
Java中给我们提供了一些同步容器(Collection),这些容器本身是线程安全的,但是对于一些复合操作,有时就需要额外的客户端加锁进行保护。复合操作包括迭代(反复获取元素,直到容器中的最后一个元素)、导航(根据一定顺序查找下一元素)、条件运算(比如缺少即加入)。这种复合操作对于本身是线程安全的同步容器来说,如果多个线程并发访问,可能就会出现问题。比如,线程安全的vector容器,他的获取最...原创 2019-02-26 17:16:12 · 1057 阅读 · 0 评论 -
Java多线程学习(九)CyclicBarrier学习
CyclicBarrier类似于闭锁,但是CyclicBarrier要等待一组线程同时到达某个屏障,先到达的线程要等待其他线程到达,等达到了屏障要求的线程数量,这些线程才能继续执行。API中的解释:CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待...原创 2019-02-26 16:59:31 · 518 阅读 · 0 评论 -
Java回调机制和作用解析
Java中一个类A中的方法调用另一个类B中的方法,可以直接调用,如果需要被调用的类B返回处理的结果,也可以直接调用,但是这些调用都是同步调用,如果类B处理的时间较长,那么类A就需要一直等待在那里,这时候可以用到异步调用,使用Future+Callable的方式,等待异步线程执行结果,这相当于就是同步调用的一种变种,因为其本质还是方法返回一个结果,而回调是指类A调用了类B中的方法来处理,调用完他就不...原创 2019-02-26 17:17:06 · 2969 阅读 · 0 评论 -
Java内部类作用用法详解
Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。内部类包括四种:成员内部类、局部内部类、匿名内部类和静态内部类。内部类的作用:1.Java只支持单重继承,想扩展功能,去实现接口吧。很快Java的设计者就发现了他们犯了矫枉过正的错误,多重继承还是有一定用处的。比如每一个人都是同时继承父亲和母亲两个类,要不然你的身体里怎么能留着父母的血呢?Java内部类应运...原创 2019-02-26 17:17:12 · 373 阅读 · 2 评论 -
Java static静态关键字
static共有5中用法,静态导入,静态变量,静态方法,静态代码块,静态内部类。所有被static修饰过的静态东西只会在类加载的时候被执行一次,并且只有这一次。1.静态导入示例: import java.lang.Math.*;public class Import { public static void main(String[] args) { double a ...原创 2019-02-26 17:17:21 · 201 阅读 · 0 评论 -
Java中四种代码块
在Java中被{}括起来的语句块称为代码块。 1.普通块,也就是局部代码块。它存在的意义是控制变量的生命周期。因为在局部代码块中的变量在外面是访问不到的,所以当我们的变量只需要用到一次的时候,即可写在局部代码块中,防止其久驻内存,占用空间。public void show(){ { System.out.println("局部代码块运行!"); }...原创 2019-02-26 17:17:25 · 411 阅读 · 0 评论 -
Java 冒泡排序,选择排序,插入排序,快速排序,归并排序
冒泡排序法每次排序将最大的一个数字放到数组末尾,第二次排序将第二大的排到数组倒数第二个位置,如此重复,直到排完。时间复杂度为O(n^2),因为经历了两个for循环。第一层i的循环代表每个元素都要比较一轮。第二层j=0表示从每一轮都要第一个开始比。j<a.length - 1 - i的原因是后面i个元素已经排好了,已经为最大的几个了,无需再比较。public static...原创 2019-02-26 17:18:54 · 724 阅读 · 0 评论 -
java 二分查找法 递归法
因为每次都将搜索范围变为原来的二分之一,当范围长度被缩短为1的时候,就完成了查找。所以二分查找法的时间复杂度为O(logN)。 如果一个算法用常数时间(O(1))将问题的大小削减为其一部分(通常是1/2),那么该算法就是(O(logN))。2^x = N 所以x=log2N。代码如下 public static int binarySearch() { i...原创 2019-02-26 17:18:59 · 535 阅读 · 0 评论 -
java多线程之生产者消费者模型
生产者-消费者模型生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。解决方法就是一个线程负责生产数据,放到共享区域,然后通知另一个线程去消耗数据。如果没有wait()和notify(),消费者线程就要不停去检查是否有数据被产生。代码如下:...原创 2019-02-26 17:19:26 · 302 阅读 · 0 评论 -
多线程怎么避免死锁
当两个线程同时运行时,A线程拥有lock A,在等待lock B,而B线程拥有lock B,在等待lock A,那么这两个线程都在等待对方释放锁,并且谁也不会先释放锁,那么就陷入了死锁。死锁的解决办法有三个,设置加锁顺序、设置加锁时限、开启死锁检测。 加锁顺序当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁...原创 2019-02-26 17:19:49 · 3782 阅读 · 1 评论 -
java多线程sleep,wait,yield方法区别
sleep()方法sleep()的作用是在指定的毫秒数内让当前“正在执行的线程”休眠(暂停执行)。这个“正在执行的线程”是指this.currentThread()返回的线程。sleep方法有两个重载版本:sleep(long millis) //参数为毫秒sleep(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒sle...原创 2019-02-26 17:19:58 · 1079 阅读 · 0 评论 -
java静态代理和动态代理理解
静态代理: 就是自己编写一个代理类来代理一个具体的类,使使用这个类的客户端不需要知道实现类是什么,怎么做的,而客户端只需知道和使用代理即可,也就是把客户端和具体类进行了解耦合。这个关系可以用明星和经纪人来类比。编写一个接口明星:package staticProxy;public interface Superstar { public void showUp(); publi...原创 2019-02-26 17:23:01 · 300 阅读 · 0 评论