- 博客(41)
- 收藏
- 关注
原创 gRPC
gRPC是Google开源的一个RPC框架,基于HTTP2.0传输数据,数据序列化框架为Google开源的Protocol Buffers一、先简单介绍下Protocol Buffers同样作为数据序列化框架,Protocol Buffers比XML更小、更快、更易于编程,它将消息和服务定义在.proto文件中,语言无关,在Java中用它自己的编译器将.proto文件直接编译成Java...
2018-08-14 14:40:40 1085
原创 Java的字面量和符号引用
最近看jvm时遇到了“字面量”和“符号引用”这两个概念,它们被存放在运行时常量池,看了一些博客以后对这两个概念有了初步认识。字面量可以理解为实际值,int a = 8中的8和String a = "hello"中的hello都是字面量符号引用就是一个字符串,只要我们在代码中引用了一个非字面量的东西,不管它是变量还是常量,它都只是由一个字符串定义的符号,这个字符串存在常量池里,类加载的时候第...
2018-07-28 23:07:29 7862 1
原创 RPC入门
RPC全称是远程过程调用(Remote Procedure Call),在分布式系统中,可以在客户机上调用服务器上的服务。RPC给我们解决了这些问题:通讯问题寻址问题数据序列化与反序列化虽然HTTP接口也可以进行远程服务调用,但由于RPC是由TCP协议支持的(也有基于HTTP协议的RPC框架),效率更高,并且RPC一般有注册中心,可以有丰富的监控管理,还可以支持长连接,所以大型...
2018-07-26 14:43:56 287
原创 Java8的Stream流详解
首先,Stream流有一些特性:Stream流不是一种数据结构,不保存数据,它只是在原数据集上定义了一组操作。这些操作是惰性的,即每当访问到流中的一个元素,才会在此元素上执行这一系列操作。Stream不保存数据,故每个Stream流只能使用一次。关于应用在Stream流上的操作,可以分成两种:Intermediate(中间操作)和Terminal(终止操作)。中间操作的返回结果都是...
2018-07-24 13:10:22 65869 12
原创 String类的一些问题
1.==比较问题String a = "hello";String b = "hello";String c = "he" + "llo";String d = "he" + new String("llo");a == b //1a == c //2a == d //3首先公布答案,式子1返回true,式子2返回true,式子3返回false式子1很好理解,由于存在字面
2018-03-28 18:48:02 409
原创 Java线程安全的集合详解
一、早期线程安全的集合我们先从早期的线程安全的集合说起,它们是Vector和HashTable1.VectorVector和ArrayList类似,是长度可变的数组,与ArrayList不同的是,Vector是线程安全的,它给几乎所有的public方法都加上了synchronized关键字。由于加锁导致性能降低,在不需要并发访问同一对象时,这种强制性的同步机制就显得多余,所以现在Vector已被弃用
2018-03-25 18:52:32 85047 7
原创 内存区域
一、所有线程共享的数据区1.Java堆(Java Heap)Java堆是虚拟机所管理的内存中最大的一块,在虚拟机启动时创建,它是几乎所有对象实例的存放区域,也是GC管理的主要区域2.方法区(Method Area)存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,GC在这个区域比较少出现3.运行时常量池(Runtime Constant Pool)运行时常量池是方法区的一部分
2018-03-22 00:37:08 172
原创 事务(以MySQL为例)
事务指逻辑上对数据库的一组操作,事务有以下四大特性:1.原子性:事务的一组操作捆绑在一起,要么全都执行,要么都不执行 2.一致性:事务的完成使数据库从一致性状态转到一致性状态,一致性也就是指数据的正确性或者稳定的一种状态,例如A给B转账的操作中,A的余额减少但B的余额还未增多的时刻,此时数据库就没有处于一致性的状态 3.隔离性:多个并发事务之间要相互隔离,不能产生干扰 4.持久性:事务一...
2018-03-21 23:29:39 226
原创 索引
索引分为聚集索引和非聚集索引,我们平时建表时用到的主键其实就是聚集索引,大部分的查询操作,最后都是通过聚集索引也就是主键才得到想要的数据的。聚集索引加了主键以后,整个表就按照主键形成了平衡树结构,其他信息都存储在叶结点。与不加主键相比,查询时间复杂度从O(n)变成了O(logn)非聚集索引非聚集索引也就是我们平时所说的常规索引,它的使用场景如下: 我们在查询时并不知道主键的值,而是通过其他字段形成
2018-03-21 22:39:09 182
原创 范式
范式可以理解为数据库中某张表的结构达到的某种设计标准的级别,标志着其结构的合理化程度,从低到高依次是1NF、2NF、3NF、BCNF、4NF、5NF,这里我只说到BCNF即可,包括BCNF在内的高级别的范式在实际开发中可能很少用到第一范式(1NF)第一范式的含义是:表中每个属性都不可分割第二范式(2NF)第二范式的含义是:在满足第一范式的基础上,要求表中所有非主键属性都要完全依赖于主键,而不能部分依
2018-03-21 22:08:00 271
原创 KMP算法
KMP是字符串模式匹配算法,用来求解模式串在主串中第一次出现的位置 简单模式匹配算法,其主串指针会回溯,时间复杂度为O(mn)//简单模式匹配算法public int getIndex(String s, String t) { for (int i = 0; i <= s.length() - t.length(); i++) { int k = i;
2018-03-14 16:39:08 153
原创 二叉树的遍历
结构:public class BiTree { public BiTree lchild; public BiTree rchild; public int element; public boolean isVisited = false; public boolean isPolled = false; public BiTree(int ele
2018-03-14 13:27:52 141
原创 二叉树的应用
1.二叉排序树 左子树上的关键字都小于根结点关键字,右子树上的关键字都大于根结点关键字,查找时间复杂度为O(log₂n) 二叉排序树构造方法:public void bstInsert(BiTree b, int k) { if (b == null) { b = new BiTree(k); return; } if (k == b.el
2018-03-14 13:22:42 323
原创 排序算法整理
先把常用排序算法进行分类: 插入排序 直接插入排序、折半插入排序、希尔排序 交换排序 冒泡排序、快速排序 选择排序 简单选择排序、堆排序 归并排序 基数排序 下面我们一个一个来...
2018-03-06 19:17:51 191
原创 爬取网易云音乐评论过万歌曲
看到网上其他同学的思路是爬取所有歌单,然后筛选出评论过万的歌曲。但我觉得不同歌单之间会有交叉,这种方式可能效率不高,而且可能会有漏网之鱼。所以我准备爬取所有歌手,再爬取他们的热门50单曲,从中筛选评论过万的歌曲。现阶段几乎没有歌手有超过50首评论过万的歌曲,所以这种方法目前是可行的。查看歌手页面,歌手被分成了华语男歌手、华语女歌手、欧美男歌手……共计15个板块,板块代号如下:group = ['10
2018-01-20 20:26:42 3163
原创 Queue总结
Queue接口声明:public interface Queue<E> extends Collection<E>方法:boolean add(E e);//超出界限抛异常boolean offer(E e);//超出界限直接返回falseE remove();//抛异常E poll();//可返回空值E element();//抛异常E peek();//可返回空值Deque接口声明:p
2018-01-20 19:43:42 270
原创 Set总结
Set接口声明public interface SetE> extends CollectionE>接口定义的方法:int size();boolean isEmpty();boolean contains(Object o);Iterator iterator();Object[] toArray(); T[] toArray(T[] a);boolean a
2018-01-20 18:01:31 212
原创 Collection旗下抽象类AbstractCollection
public abstract class AbstractCollection<E> implements Collection<E>我们来看AbstractCollection为Collection接口中的哪些方法提供了实现public boolean isEmpty(){}public boolean contains(Object o){}public Object[] toArray(
2018-01-19 23:34:00 269
原创 List总结
List接口源码分析public interface List<E> extends Collection<E>继承了Collection接口中的所有方法,并且有自己的新增方法://继承于Collection接口的方法int size();boolean isEmpty();boolean contains(Object o);Iterator<E> iterator();Object[]
2018-01-19 23:26:40 213
原创 两大集合接口之——Collection
public interface Collection<E> extends Iterable<E>Collection继承了Iterable接口,即继承了Iterable接口中的方法:Iterator<T> iterator();default void forEach(Consumer<? super T> action);接下来看Collection接口定义的方法:int size();b
2018-01-19 23:01:57 326
原创 Map旗下映射类总结
java.util包中,Map旗下的映射类有这六个:HashMap、LinkedHashMap、IdentityHashMap、WeakHashMap、TreeMap、EnumMap,下面一一分析1.HashMappublic class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializabl
2018-01-18 22:53:51 240
原创 内部类
内部类的几个应用点: 1.访问该类定义所在的作用域中的数据,包括私有数据 2.可以对同一个包中的其他类隐藏起来 3.匿名内部类可以应用于回调函数关于数据访问内部类可以直接访问其外围类的所有数据,包括私有数据。 在内部类之外、外围类之内可以直接访问内部类,例如构造一个内部类对象:object o = new InnerClass();也可以更准确地构造一个内部类对象:object o = th
2018-01-18 15:58:45 155
原创 Lambda表达式
Java是面向对象编程而不是面向函数编程,是不能把方法名作为参数传递给一个方法的,若想把一个行为作为参数传递给方法,只能采用匿名类的形式,非常繁琐,如下:new Thread(new Runnable() { @Override public void run() { System.out.println("Before Java8, too much code f
2018-01-18 12:20:19 173
原创 接口
1.接口不是类,是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义2.接口中的方法自动地属于public,接口中的域自动地属于public static final3.接口中可以定义常量,但不能含有实例域,通常也不能实现方法4.不能使用new实例化接口,可以声明接口变量,并引用实现了接口的类对象5.可以使用instance检查一个对象是否实现了某个特定的接口6.Java SE 8中可以在接
2018-01-17 16:37:00 157
原创 Map旗下抽象类AbstractMap
public abstract class AbstractMap<K,V> implements Map<K,V>此抽象类提供了一些成员变量和方法,可以直接被映射类继承transient Set<K> keySet;transient Collection<V> values;public int size() { return entrySet().size();}publi
2018-01-15 16:51:15 265
原创 Map旗下两接口——SortedMap和NavigableMap
先看SortedMap,它直接继承了Map:public interface SortedMap<K,V> extends Map<K,V>顾名思义,此接口应该与排序有关,以下是它的一些方法:Comparator<? super K> comparator();//按key升序排列,返回子映射,fromKey到toKey,包括fromKey,不包括toKeySortedMap<K,V> subMa
2018-01-15 00:39:08 3025
原创 两大集合接口之——Map
让我们通过读Map接口的源码,来了解一下Map系列集合的一些特性和方法:public interface Map<K,V>从接口定义可以看出,Map中的元素是以K-V键值对的形式存在的int size();boolean isEmpty();boolean containsKey(Object key);boolean containsValue(Object value);V get(Ob
2018-01-14 23:24:36 287
原创 同步器
线程之间相互合作时,需要用到同步器来完成同步,下面介绍几种常用同步器:1.Semaphore(信号量) 信号量数量限制了访问资源的线程总数,线程请求会消耗一个信号量,当信号量为0时,新的线程会阻塞,直到有线程释放了一个信号量线程类:package Semaphore;import java.util.concurrent.Semaphore;public class SemaphoreThread
2018-01-07 16:33:17 856
原创 线程池
一、线程池的构造使用线程池离不开ThreadPoolExecutor类,该类实现了ExecutorService接口,其构造方法如下:public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,Thre
2018-01-07 01:57:22 170
原创 创建线程的三种方法
方法一:继承Thread类 方法二:实现Runnable接口 方法三:实现Callable接口前两种方法需要重写run方法,第三种方法需要重写call方法。因为Java不允许多继承,允许实现多个接口,所以方法二比方法一灵活。方法三与方法二类似,但可以获得返回值,功能更强大。用Callable对象实例化一个FutureTask对象,FutureTask对象既可以像Runnable对象那样用来实例化
2018-01-06 16:59:32 250
原创 阻塞队列
对于多线程间的数据共享,可以使用阻塞队列(BlockingQueue)来实现,它为我们自动管理多线程环境下的等待与唤醒问题,让程序员可以忽略这些细节,专注于高层次的业务功能。会抛出异常的方法: add(添加一个元素)、element(返回队列的头元素)、remove(移出并返回头元素) 会阻塞的方法: put(添加一个元素)、take(移出并返回头元素) 不抛出异常不阻塞只改变返回值的方法:
2018-01-05 23:36:20 169
原创 读/写锁
如果有很多线程同时读取数据而只有很少线程写入数据,那么允许读者线程共享访问,对性能有很大提升,在此情况下使用读/写锁。读锁可以被多个读操作共用,但排斥所有写操作;写锁排斥所有其他的读操作和写操作。private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();private Lock readLock = rwl.readLock(
2018-01-05 21:37:31 217
原创 锁测试与超时
先来比较一下Lock的四个锁方法:1.void lock() 在等待获取锁的过程中休眠,禁止一切线程调度2.void lockInterruptibly() throws InterruptedException 在等待获取锁的过程中可以被中断,被中断后抛出异常3.boolean tryLock() 获取到锁返回true,获取不到锁返回false,不会等待4.boolean tryLock(l
2018-01-05 21:27:05 506
原创 ThreadLocal
synchronized和ThreadLocal都是应用于线程共享变量时的方法,但它们对应的应用场景不同。我们可以这样理解,多个线程共享同一个对象的变量,当多个线程需要维护的是同一个变量值时(即同一个时刻该变量一定只有唯一值是正确的),则用synchronized进行同步;然而当多个线程需要维护的不是同一个变量值时,它们只需要获取该变量的初始值,该变量在每个线程中的值都是独立的、无关的,则用Thre
2018-01-03 21:37:50 201
原创 final关键字
final关键字通常被用来修饰不希望被修改的变量,在多线程环境中,它通过保证指令有序性起作用,即如果一个对象在初始化期间有可能被其他线程访问,那么就是不安全的,final关键字防止了指令重排,保证对象创建完成之后才会被其他线程调用。也可以这么理解,对于那些不被修改的变量,它们天生就是线程安全的,但唯一会出现问题的点就是在对象初始化的过程中它们被其他线程访问到。用final关键字修饰这些变量,就彻底保
2017-12-30 00:48:01 211
原创 volatile关键字
volatile关键字是一种比synchronized更轻量级的同步方法,它提供了一种免锁机制。与synchronized相比,volatile可以保证可见性、有序性,但不能保证原子性,所以只有在一些对原子性没有要求的场合才可以用volatile代替synchronized。可见性:普通情况下线程读数据时把数据从内存读到自己的缓存区,以后可能会直接从缓存区读取,而不经过内存,写数据时也是先写入缓存区
2017-12-30 00:31:19 141
原创 线程同步
1.锁对象 用ReentrantLock(可重入锁)类可以声明一个锁对象,一般情况下它和synchronized(锁对象){}的用法相似,但它有更多高级功能,暂时不做讨论,使用方式如下:ReentrantLock lock = new ReentrantLock();lock.lock();try{ ...}finally{ lock.unlock();}2.条件对象
2017-12-29 00:10:02 142
原创 守护线程
守护线程(daemon thread)只是用来为其他线程提供服务,例如垃圾处理线程,当所有其他线程都终止只剩下守护线程时,虚拟机就退出了。不要让守护线程去访问固有资源,如文件、数据库,因为它可能在任何时候中断,不安全。可以用setDaemon(true)方法把一个线程设置为守护线程。下面是使用守护者线程的一个例子: 两个线程,一个为写日志线程,一个为清理日志线程,我们把后者设置为守护线程,这样当前
2017-12-28 22:40:01 512
原创 线程阻塞
广义上的线程阻塞又可以细分为阻塞和等待两种:阻塞指线程试图获取的对象锁被其他线程持有导致线程被阻塞,此过程发生在synchronized代码块之外,是被动的。等待指线程通过调用wait或sleep方法进入等待状态,此过程发生在synchronized代码块之内,是主动的。前者释放了锁,需要另外一个线程在持有同一个对象锁的同步代码块之内调用notify方法唤醒等待线程;后者没有释放锁,在计时结束后自动
2017-12-28 00:29:49 288
原创 线程中断
调用Thread对象的stop方法可以强制终止线程,但这种方法只是简单粗暴地终止线程,线程可能存在未做完的工作和未释放的资源,是一种不安全的方法,所以已经被弃用。正确的终止线程的方法是设置flag标志,在run方法中用while循环不断检查flag,而在需要终止线程的地方修改flag,这样就能让线程在本次while循环中完成任务,在下一次while循环判断时被终止,这种方法是安全的。但要注意,线程被
2017-12-28 00:14:40 253
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人