高级编程
文章平均质量分 94
无心六神通
金融科技系统架构师
展开
-
Java-泛型-通配符-详解
泛型类型是固定的,某些场景下使用起来不太灵活,于是,通配符就来了!通配符可以允许类型参数变化,用来解决泛型无法协变的问题。无界通配符可以接收任何泛型类型数据,用于实现不依赖于具体类型参数的简单方法,可以捕获参数类型并交由泛型方法进行处理。List<?> 和 List 有区别吗?** 当然有!List<?> list 表示 list 是持有某种特定类型的 List,但是不知道具体是哪种类型。因此,我们添加元素进去的时候会报错。原创 2024-02-06 03:21:27 · 798 阅读 · 0 评论 -
Java-序列化-详解
如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。序列化: 将数据结构或对象转换成二进制字节流的过程反序列化:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在 C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而 class 对应的是对象类型。原创 2024-02-06 03:19:13 · 821 阅读 · 0 评论 -
Java-IO模型-详解
I/O 一直是很多小伙伴难以理解的一个知识点,这篇文章我会将我所理解的 I/O 讲给你听,希望可以对你有所帮助。原创 2024-02-06 03:14:50 · 1210 阅读 · 0 评论 -
Java-并发编程-常见面试题-总结
悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。像 Java 中和等独占锁就是悲观锁思想的实现。悲观锁通常多用于写多比较多的情况下(多写场景),避免频繁失败和重试影响性能。原创 2024-01-30 11:09:28 · 1095 阅读 · 0 评论 -
Java-JMM-内存模型-详解
Java 是最早尝试提供内存模型的编程语言。由于早期内存模型存在一些缺陷(比如非常容易削弱编译器的优化能力),从 Java5 开始,Java 开始使用新的内存模型。一般来说,编程语言也可以直接复用操作系统层面的内存模型。不过,不同的操作系统内存模型不同。如果直接复用操作系统层面的内存模型,就可能会导致同样一套代码换了一个操作系统就无法执行了。Java 语言是跨平台的,它需要自己提供一套内存模型以屏蔽系统差异。这只是 JMM 存在的其中一个原因。原创 2024-02-06 03:04:21 · 800 阅读 · 0 评论 -
Java-线程池-最佳实践
一般建议是不同的业务使用不同的线程池,配置线程池的时候根据当前业务的情况对当前线程池进行配置,因为不同的业务的并发以及对资源的使用情况都不同,重心优化系统性能瓶颈相关的业务。原创 2024-02-06 03:02:26 · 829 阅读 · 0 评论 -
Java-常见并发容器-总结
在很多应用场景中,读操作可能会远远大于写操作。由于读操作根本不会修改原有的数据,因此对于每次读取都进行加锁其实是一种资源浪费。我们应该允许多个线程同时访问List的内部数据,毕竟读取操作是安全的。这和我们之前提到过的读写锁的思想非常类似,也就是读读共享、写写互斥、读写互斥、写读互斥。JDK 中提供了类比相比于在读写锁的思想又更进一步。为了将读取的性能发挥到极致,读取是完全不用加锁的,并且更厉害的是:写入也不会阻塞读取操作。只有写入和写入之间需要进行同步等待。这样一来,读操作的性能就会大幅度提升。原创 2024-02-06 03:01:17 · 833 阅读 · 0 评论 -
Java-Atomic-原子类-总结
Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。所以,所谓原子类说简单点就是具有原子/原子操作特征的类。并发包的原子类都存放在下,如下图所示。根据操作的数据类型,可以将 JUC 包中的原子类分为 4 类基本类型使用原子的方式更新基本类型:整型原子类AtomicLong:长整型原子类:布尔型原子类数组类型。原创 2024-02-06 03:00:01 · 1030 阅读 · 0 评论 -
Java-并发编程-CompletableFuture
同时实现了Future和接口。除了提供了更为好用和强大的Future特性之外,还提供了函数式编程的能力。Future:尝试取消执行任务。:判断任务是否被取消。: 判断任务是否已经被执行完成。get():等待任务执行完成并获取运算结果。:多了一个超时时间。接口描述了一个异步计算的阶段。很多计算可以分成多个阶段或步骤,此时可以通过它将所有步骤组合起来,形成异步计算的流水线。接口中的方法比较多,的函数式能力就是这个接口赋予的。从这个接口的方法参数你就可以发现其大量使用了 Java8 引入的函数式编程。原创 2024-02-03 19:59:52 · 1077 阅读 · 0 评论 -
Java-并发编程-ThreadLocal
对于,大家的第一反应可能是很简单呀,线程的变量副本,每个线程隔离。的 key 是弱引用,那么在的时候,发生GC之后,key 是否为null?中的数据结构?的Hash 算法?中Hash 冲突如何解决?的扩容机制?中过期 key 的清理机制?探测式清理和启发式清理流程?方法实现原理?方法实现原理?项目中使用情况?遇到的坑?......上述的一些问题你是否都已经掌握的很清楚了呢?本文将围绕这些问题使用图文方式来剖析的点点滴滴。原创 2024-02-03 19:56:30 · 935 阅读 · 0 评论 -
Java-并发编程-AQS
AQS 的全称为,翻译过来的意思就是抽象队列同步器。这个类在包下面。AQS 就是一个抽象类,主要用来构建锁和同步器。AQS 为构建锁和同步器提供了一些通用功能的是实现,因此,使用 AQS 能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的Semaphore,其他的诸如等等皆是基于 AQS 的。使用者继承并重写指定的方法。将 AQS 组合在自定义同步组件的实现中,并调用其模板方法,而这些模板方法会调用使用者重写的方法。这和我们以往通过实现接口的方式有很大区别,这是模板方法模式很经典的一个运用。原创 2024-02-03 19:35:13 · 962 阅读 · 0 评论 -
Java-并发编程-线程池
顾名思义,线程池就是管理一系列线程的资源池,其提供了一种限制和管理线程资源的方式。每个线程池还维护一些基本统计信息,例如已完成任务的数量。降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。原创 2024-02-03 19:31:54 · 895 阅读 · 0 评论 -
Java-并发编程-乐观锁和悲观锁
悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。像 Java 中和等独占锁就是悲观锁思想的实现。悲观锁通常多用于写比较多的情况下(多写场景),避免频繁失败和重试影响性能。原创 2024-02-03 19:24:33 · 789 阅读 · 0 评论 -
Java-IO-设计模式-总结
IO 流中的字符流和字节流的接口不同,它们之间可以协调工作就是基于适配器模式来做的,更准确点来说是对象适配器。更侧重于让接口不兼容而不能交互的类可以一起工作,当我们调用适配器对应的方法时,适配器内部会调用适配者类或者和适配类相关的类的方法,这个过程透明的。更侧重于动态地增强原始类的功能,装饰器类需要跟原始类继承相同的抽象类或者实现相同的接口。装饰器模式通过组合替代继承来扩展原始类的功能,在一些继承关系比较复杂的场景(IO 这一场景各种类的继承关系就比较复杂)更加实用。的子类比较少的话,这样做是没问题的。原创 2024-01-28 23:36:47 · 912 阅读 · 0 评论 -
Java-IO-基础知识-总结
IO 即,输入和输出。数据输入到计算机内存的过程即输入,反之输出到外部存储(比如数据库,文件,远程主机)的过程即输出。数据传输过程类似于水流,因此称为 IO 流。IO 流在 Java 中分为输入流和输出流,而根据数据的处理方式又分为字节流和字符流。Java IO 流的 40 多个类都是从如下 4 个抽象类基类中派生出来的。Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。原创 2024-01-28 23:32:45 · 902 阅读 · 0 评论 -
Java-源码-ConcurrentHashMap-底层-数据结构
Java7 中使用的分段锁,也就是每一个 Segment 上同时只有一个线程可以操作,每一个Segment都是一个类似HashMap数组的结构,它可以扩容,它的冲突会转化为链表。但是Segment的个数一但初始化就不能改变。Java8 中的使用的锁加 CAS 的机制。结构也由 Java7 中的 Segment数组 +HashEntry数组 + 链表进化成了Node 数组 + 链表 / 红黑树,Node 是类似于一个 HashEntry 的结构。原创 2024-01-28 23:31:21 · 821 阅读 · 0 评论 -
Java-源码-HashMap-底层数据结构
HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现,是常用的 Java 集合之一,是非线程安全的。HashMap可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后的HashMap。原创 2024-01-28 23:29:51 · 856 阅读 · 0 评论 -
Java-源码-ArrayList-扩容机制
ArrayList的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用操作来增加ArrayList实例的容量。这可以减少递增式再分配的数量。ArrayList继承于 AbstractList,实现了 List这些接口。是一个标志接口,表明实现这个接口的 List 集合是支持快速随机访问的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象,这就是快速随机访问。ArrayList实现了 Cloneable接口,即覆盖了函数。原创 2024-01-28 23:28:29 · 830 阅读 · 0 评论 -
Java-集合-使用注意事项-总结
就是起一个模板的作用,指定了返回数组的类型,0 是为了节省空间,因为它只是为了说明返回的类型。方法的时间复杂度也是 O(1),不过,也有很多复杂度不是 O(1) 的,比如。方法,时间复杂度接近于 O(1)(没有出现哈希冲突的时候为 O(1))。方法是通过遍历所有元素的方法来做的,时间复杂度接近是 O(n)。的真正得到的参数就不是数组中的元素,而是数组对象本身!的唯一元素就是这个数组,这也就解释了上面的代码。的简易源码,我们可以看到这个类重写的方法有哪些。方法的可读性更好,并且时间复杂度为 O(1)。原创 2024-01-28 23:26:45 · 746 阅读 · 0 评论 -
Java-常见面试题-集合-总结
为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀。我们上面也讲到了过了,Hash 值的范围值-2147483648 到 2147483647,前后加起来大概 40 亿的映射空间,只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但问题是一个 40 亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是“(n 代表数组长度)。原创 2024-01-28 23:25:17 · 815 阅读 · 0 评论 -
Java-重要知识点-语法塘详解
语法糖(Syntactic Sugar)也称糖衣语法,是英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。简而言之,语法糖让程序更加简洁,有更高的可读性。有意思的是,在编程领域,除了语法糖,还有语法盐和语法糖精的说法,篇幅有限这里不做扩展了。我们所熟知的编程语言中几乎都有语法糖。作者认为,语法糖的多少是评判一个语言够不够牛逼的标准之一。原创 2024-01-28 23:23:05 · 781 阅读 · 0 评论 -
Java-重要知识点-SPI机制详解
其实不难发现,SPI 机制的具体实现本质上还是通过反射完成的。我们按照规定将要暴露对外使用的具体实现类在文件下声明。另外,SPI 机制在很多框架中都有应用:Spring 框架的基本原理也是类似的反射。还有 Dubbo 框架提供同样的 SPI 扩展机制,只不过 Dubbo 和 spring 框架中的 SPI 机制具体实现方式跟咱们今天学得这个有些细微的区别,不过整体的原理都是一致的,相信大家通过对 JDK 中 SPI 机制的学习,能够一通百通,加深对其他高深框的理解。原创 2024-01-28 23:21:48 · 950 阅读 · 0 评论 -
Java-魔法类-Unsafe-应用解析-美团技术团队
Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。原创 2024-01-28 23:18:19 · 788 阅读 · 0 评论 -
Java-重要知识点-魔法类Unsafe详解
Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升 Java 运行效率、增强 Java 语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使 Java 语言拥有了类似 C 语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得 Java 这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。原创 2024-01-28 23:16:46 · 970 阅读 · 0 评论 -
Java-重要知识点-BigDecimal详解
BigDecimal可以实现对浮点数的运算,不会造成精度丢失。通常情况下,大部分需要浮点数精确运算结果的业务场景(比如涉及到钱的场景)都是通过BigDecimal来做的。浮点数之间的等值判断,基本数据类型不能用 == 来比较,包装数据类型不能用 equals 来判断。具体原因我们在上面已经详细介绍了,这里就不多提了。想要解决浮点数运算精度丢失这个问题,可以直接使用BigDecimal来定义浮点数的值,然后再进行浮点数的运算操作即可。// 0。原创 2024-01-28 23:15:16 · 758 阅读 · 0 评论 -
Java-重要知识点-反射机制详解
让我们在运行时有了分析操作类的能力,这同样也增加了安全问题。另外,反射的性能也要稍差点,不过,对于框架来说实际是影响不大的。但是我们一般是不知道具体类的,基本都是通过遍历包下面的类来获取 Class 对象,通过此方式获取 Class 对象不会进行初始化。这些都是因为你可以基于反射分析类,然后获取到类/属性/方法/方法的参数上的注解。反射之所以被称为框架的灵魂,主要是因为它赋予了我们在运行时分析类以及执行类中方法的能力。通过反射你可以获取任意一个类的所有属性和方法,你还可以调用这些方法和属性。原创 2024-01-28 23:13:40 · 795 阅读 · 0 评论 -
Java-重要知识点-为什么Java中只有值传递
Java 中将实参传递给方法(或函数)的方式是值传递如果参数是基本类型的话,很简单,传递的就是基本类型的字面量值的拷贝,会创建副本。如果参数是引用类型,传递的就是实参所引用的对象在堆中地址值的拷贝,同样也会创建副本。原创 2024-01-28 23:12:03 · 787 阅读 · 0 评论 -
Java-即时编译器-原理-实践-美团技术团队
本文主要介绍了JIT即时编译的原理以及在美团一些实践的经验,还有最前沿的即时编译器的使用效果。作为一项解释型语言中提升性能的技术,JIT已经比较成熟了,在很多语言中都有使用。对于Java服务,JVM本身已经做了足够多,但是我们还应该不断深入了解JIT的优化原理和最新的编译技术,从而弥补JIT的劣势,提升Java服务的性能,不断追求卓越。原创 2024-01-27 09:57:56 · 877 阅读 · 0 评论 -
前端-高级编程-函数式编程(下)-美团技术团队
本文通过深入函数式编程的副作用处理及实际应用场景,提供一个学习和使用函数式编程的视角给读者。一方面,这种副作用管理方式是一种高级的抽象形式,不易理解;另一方面,我们在学习和使用函数式编程的过程中,几乎都会遇到类似的副作用问题需要解决,能否解决这个问题也决定了一门函数式编程语言最终是否能走上成功。副作用处理方式函数式编程的应用函数式编程的优缺点比较先思考一个问题,下面两个定义有什么区别?图 45num1是数字类型,而num2是对象类型,这是一个直观的区别。不过,不仅仅如此。原创 2024-01-20 06:18:44 · 887 阅读 · 0 评论 -
前端-高级编程-函数式编程(上)-美团技术团队
本文分为上下两篇,上篇讲述函数式编程的基础概念和特性,下篇讲述函数式编程的进阶概念、应用及优缺点。函数式编程既不是简单的堆砌函数,也不是语言范式的终极之道。我们将深入浅出地讨论它的特性,以期在日常工作中能在对应场景中进行灵活应用。函数式编程是一种风格范式,没有一个标准的教条式定义。我们来看一下维基百科的定义:函数式编程是一种编程范式,它将电脑运算视为函数运算,并且避免使用程序状态以及易变对象。其中,λ演算是该语言最重要的基础。而且λ演算的函数可以接受函数作为输入的参数和输出的返回值。避免状态变更。原创 2024-01-19 20:35:38 · 853 阅读 · 0 评论