简栈文化

Java技术人的成长之路~


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

Java深拷贝和浅拷贝

发表于 2020-02-25 | 更新于: 2020-08-02 | 分类于 Java
对象拷贝有哪些对象拷贝(Object Copy)就是将一个对象的属性拷贝到另一个有着相同类类型的对象中去。在程序中拷贝对象是很常见的,主要是为了在新的上下文环境中复用对象的部分或全部数据。 Java中有三种类型的对象拷贝: 浅拷贝(Shallow Copy) 深拷贝(Deep Copy) 延迟拷贝(Lazy Copy) 理解浅拷贝什么是浅拷贝? 浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。 如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。 在上图中,SourceObject有一个int类型的属性 “field1”和一个引用类型属性”refObj”(引用ContainedObject类型的对象)。当对SourceObject做浅拷贝时,创建了CopiedObject,它有一个包含”field1”拷贝值的属性”field2”以及仍指向refObj本身的引用。由于”field1”是基本类型,所以只是将它的值拷贝给”field2”,但是 ...
阅读全文 »

Java程序员必须要了解的类Unsafe

发表于 2020-02-24 | 更新于: 2020-08-02 | 分类于 Java
前言Java是一个安全的编程语言,它能最大程度的防止程序员犯一些低级的错误(大部分是和内存管理有关的)。但凡是不是绝对的,使用Unsafe程序员就可以操作内存,因此可能带来一个安全隐患。 这篇文章是就快速学习下sun.misc.Unsafe的公共API和一些有趣的使用例子。 Unsafe 实例化在使用Unsafe之前我们需要先实例化它。但我们不能通过像Unsafe unsafe = new Unsafe()这种简单的方式来实现Unsafe的实例化,这是由于Unsafe的构造方法是私有的。Unsafe有一个静态的getUnsafe()方法,但是如果天真的以为调用该方法就可以的话,那你将遇到一个SecurityException异常,这是由于该方法只能在被信任的代码中调用。 123456public static Unsafe getUnsafe() { Class cc = sun.reflect.Reflection.getCallerClass(2); if (cc.getClassLoader() != null) throw new Secur ...
阅读全文 »

我们如何看SpringBoot的源代码

发表于 2020-02-23 | 更新于: 2020-08-02 | 分类于 Spring
Volatile简介volatile被称为轻量级的synchronized,运行时开销比synchronized更小,在多线程并发编程中发挥着同步共享变量、禁止处理器重排序的重要作用。建议在学习volatie之前,先看一下Java内存模型《什么是Java内存模型?》,因为volatile和Java内存模型有着莫大的关系。 Java内存模型在学习volatie之前,需要补充下Java内存模型的相关(JMM)知识,我们知道Java线程的所有操作都是在工作区进行的,那么工作区和主存之间的变量是怎么进行交互的呢,可以用下面的图来表示。 Java通过几种原子操作完成工作区内存和主存的交互 lock:作用于主存,把变量标识为线程独占状态。 unlock:作用于主存,解除变量的独占状态。 read:作用于主存,把一个变量的值通过主存传输到线程的工作区内存。 load:作用于工作区内存,把read操作传过来的变量值储存到工作区内存的变量副本中。 use:作用于工作内存,把工作区内存的变量副本传给执行引擎。 assign:作用于工作区内存,把从执行引擎传过来的值赋值给工作区内存的变量副本。 store ...
阅读全文 »

IO多路复用的 select、poll、epoll详解

发表于 2020-02-22 | 更新于: 2020-08-02 | 分类于 Java
前几篇文章讲述了IO的几种模式及netty的基本概念,netty基于多路复用模型下的reactor模式,对 大量连接、单个处理短且快 的场景很适用 。 那在往底层思考,linux对于IO又是如何处理的呢? C10K 问题http://www.52im.net/thread-566-1-1.html 最初的服务器都是基于进程/线程模型的,新到来一个TCP连接,就需要分配1个进程(或者线程)。而进程又是操作系统最昂贵的资源,一台机器无法创建很多进程。如果是C10K就要创建1万个进程,那么单机而言操作系统是无法承受的(往往出现效率低下甚至完全瘫痪)。如果是采用分布式系统,维持1亿用户在线需要10万台服务器,成本巨大。基于上述考虑,如何突破单机性能局限,是高性能网络编程所必须要直面的问题。这些局限和问题最早被Dan Kegel 进行了归纳和总结,并首次成系统地分析和提出解决方案,后来这种普遍的网络现象和技术局限都被大家称为 C10K 问题。 C10K 问题的最大特点是:设计不够良好的程序,其性能和连接数及机器性能的关系往往是非线性的。 举个例子:如果没有考虑过 C10K 问题,一个经典的基于 ...
阅读全文 »

HashMap JDK 1.8 后它改了什么?

发表于 2020-02-21 | 更新于: 2020-08-02 | 分类于 Java
推荐一个咕泡学院的视频资源:链接:https://pan.baidu.com/s/1SmSzrmfgbm6XgKZO7utKWg 密码:e54x 先回答一下之前发布的《使用HashMap的时候小心点》同学不补充的问题,说最好说下HashMap在JDK8下是怎么解决死循环的问题的。 链表部分对应上面 transfer 的代码: 12345678910111213141516171819202122232425262728 Node<K,V> loHead = null, loTail = null; Node<K,V> hiHead = null, hiTail = null; Node<K,V> next; do { next = e.next; if ((e.hash & oldCap) == 0) { if (loTail == null) loHead = e; else loTail.next = ...
阅读全文 »

Hash算法和一致性Hash算法

发表于 2020-02-20 | 更新于: 2020-08-02 | 分类于 Java , 算法
Hash算法Hash算法在路由算法应用中,为了保证数据均匀的分布,例如有3个桶,分别是0号桶,1号桶和2号桶;现在有12个球,怎么样才能让12个球平均分布到3个桶中呢?使用Hash算法的做法是,将12个球从0开始编号,得到这样的一个序列:0,1,2,3,4,5,6,7,8,9,10,11。将这个序列中的每个值模3,不管数字是什么,得到的结果都是0,1,2,不会超过3,将结果为0的数字放入0号桶,结果为1的数子放入1号桶,结果为2的数字放入2号桶,12个球就均匀的分布到3个桶中,0,3,6,9,12号球放入0号桶,1,4,7,10号球放入1号桶,2,5,8,11号球放入2号桶。 一致性Hash算法一致性Hash算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot Spot)问题,初衷和CARP十分相似。一致性Hash修正了CARP使用的简单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。 一致性Hash算法也是使用取模的方法,只是,刚才描述的取模法是对服务器的数量进行取模,而一致性Hash算法是对2^3 ...
阅读全文 »

Dubbo负载均衡:一致性Hash的实现分析

发表于 2020-02-19 | 更新于: 2020-08-02 | 分类于 Java , Dubbo
作者:FserSuN 来源:https://blog.csdn.net/Revivedsun/article/details/71022871 LoadBalance负责从多个Invoker中选出具体的一个用于本次调用,以分摊压力。Dubbo中LoadBalance结构如下图。 1234com.alibaba.dubbo.rpc.cluster.LoadBalance 接口提供了<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException; 通过该方法,进行结点选择。 1234com.alibaba.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance 实现了一些公共方法,并定义抽象方法protected abstract <T> Invoker<T> doSelect(List<Invoker<T>> ...
阅读全文 »

Double浮点数运算为啥会丢失精度?

发表于 2020-02-18 | 更新于: 2020-08-02 | 分类于 Java
作者:王念博客 来源:https://my.oschina.net/wangnian/blog/3064886 前言:在工作中,谈到有小数点的加减乘除都会想到用BigDecimal来解决,但是有很多人对于double或者float为啥会丢失精度一脸茫然。还有BigDecimal是怎么解决的?话不多说,我们开始。 浮点数是啥? 浮点数是计算机用来表示小数的一种数据类型,采用科学计数法。在java中,double是双精度,64位,浮点数,默认是0.0d。float是单精度,32位.浮点数,默认是0.0f; 在内存中存储 float 符号位(1bit) 指数(8 bit) 尾数(23 bit)double 符号位(1bit) 指数(11 bit) 尾数(52 bit) float在内存中指数是8bit,由于阶码实际存储的是指数的移码,假设指数的真值是e,阶码为E,则有E=e+(2^n-1 -1)。其中 2^n-1 -1是IEEE754标准规定的指数偏移量,根据这个公式我们可以得到 2^8 -1=127。于是,float的指数范围为-128 +127,而double的指数范 ...
阅读全文 »

CPU的缓存L1、L2、L3与缓存行填充

发表于 2020-02-17 | 更新于: 2020-08-02 | 分类于 CPU
L1,L2,L3 指的都是CPU的缓存,他们比内存快,但是很昂贵,所以用作缓存,CPU查找数据的时候首先在L1,然后看L2,如果还没有,就到内存查找一些服务器还有L3 Cache,目的也是提高速度。 高速缓冲存储器Cache是位于CPU与内存之间的临时存储器,它的容量比内存小但交换速度快。在Cache中的数据是内存中的一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可避开内存直接从Cache中调用,从而加快读取速度。由此可见,在CPU中加入Cache是一种高效的解决方案,这样整个内存储器(Cache+内存)就变成了既有Cache的高速度,又有内存的大容量的存储系统了。Cache对CPU的性能影响很大,主要是因为CPU的数据交换顺序和CPU与Cache间的带宽引起的。 高速缓存的工作原理1. 读取顺序CPU要读取一个数据时,首先从Cache中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的速度从内存中读取并送给CPU处理,同时把这个数据所在的数据块调入Cache中,可以使得以后对整块数据的读取都从Cache中进行,不必再调用内存。 正是这 ...
阅读全文 »

CPU Cache与高性能编程

发表于 2020-02-16 | 更新于: 2020-08-02 | 分类于 CPU
认识CPU CacheCPU Cache概述随着CPU的频率不断提升,而内存的访问速度却没有质的突破,为了弥补访问内存的速度慢,充分发挥CPU的计算资源,提高CPU整体吞吐量,在CPU与内存之间引入了一级Cache。随着热点数据体积越来越大,一级Cache L1已经不满足发展的要求,引入了二级Cache L2,三级Cache L3。(注:若无特别说明,本文的Cache指CPU Cache,高速缓存)CPU Cache在存储器层次结构中的示意如下图: 计算机早已进入多核时代,软件也越来越多的支持多核运行。一个处理器对应一个物理插槽,多处理器间通过QPI总线相连。一个处理器包含多个核,一个处理器间的多核共享L3 Cache。一个核包含寄存器、L1 Cache、L2 Cache,下图是Intel Sandy Bridge CPU架构,一个典型的NUMA多处理器结构: 作为程序员,需要理解计算机存储器层次结构,它对应用程序的性能有巨大的影响。如果需要的程序是在CPU寄存器中的,指令执行时1个周期内就能访问到他们。如果在CPU Cache中,需要130个周期;如果在主存中,需要50200个周 ...
阅读全文 »
上一页1…91011…15下一页
Vernon

Vernon

149 日志
66 分类
87 标签
RSS
GitHub E-Mail
© 2021 Vernon
由 Hexo 强力驱动
|
主题 — NexT.Gemini v6.0.4