【Java】基础知识

简介: 1,StringBuffer与StringBuilder的区别,及实现原理1、StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,2、只是StringBuffer 中的方法大都采用了synchronized关键字进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。3、在单线程程序下,String...

1,StringBuffer与StringBuilder的区别,及实现原理

1、StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,

2、只是StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的,

而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。

3、在单线程程序下,StringBuilder效率更快,因为它不需要加锁,不具备多线程安全

而StringBuffer则每次都需要判断锁,效率相对更低

实现原理

StringBuffer类继承自AbstractStringBuilder抽象类,实现Serializable序列化接口和CharSequence接口。

网络异常,图片无法展示
|
image.gif 编辑

AbstractStringBuilder抽象类实现Appendabel,CharSequence接口。

一旦定义之后不可改变,能够改变的String变量的引用地址。比如String b=new String ();指向String 创建的在堆中的对象地址,b= new String("ssss");这样b再次指向另一个在堆中的某一对象地址。而之前堆中的String对象的value是常量并没有发生改变

简而言之创建的String变量可以重新指向对象但是String的一个对象中的value数组是不能改变的这也就是为什么定义的对象无法进行末尾追加值的原因(因为你想要改变String的长度需要操作value对象而value对象呗关键字final修饰了)。

 

这三个类在进行操作时的速度关系为:StringBuilder > StringBuffer > String

由于String中进行操作时都会新建一个char[ ]数组代替原来的char[ ]数组,所以速度最慢

StringBuffer线程安全,每个方法都有synchronized同步阻塞,所以操作速度受影响

StringBuilder没有同步阻塞的限制,所以操作速度最快

使用场景

    • 如果要操作少量的数据用 = String
    • 单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
    • 多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

    2,接口和抽象类的区别

    相同点:

      • 都无法实例对象
      • 可以定义无方法体的方法

      不同点:

        1. 抽象类是一种类只能单继承   接口可以多实现
        2. 抽象类中 可以有普通方法  接口在jdk1.8之前是不可以定义普通方法的
        3. 抽象类中可以有普通变量 接口中的变量都是由final修饰的
        4. 抽象类可以有构造器和主方法(抽象类中的构造器主要是在子类的构造方法中调用  负责初始化抽象类中的参数) 接口中不可以有构造器和主方法
        5. 抽象类中的方法普通可以由public   private   protected 和默认修饰   抽象方法可以由 public protected(或者不加修饰符)修饰  抽象方法必须由abstract修饰    接口方法默认由public修饰 接口中的抽象方法只能由public修饰  default在接口中只能修饰带有方法体的方法

        使用场景

          • 当需要一些默认的方法实现时需要使用抽象类
          • 当需要多继承时使用接口
          • 当需要不断增加基础功能的时候使用抽象类  当使用接口时 增加功能就需要修改每个实现了该接口的实现类

          3 arraylist 和hashMasp 初始容量值是多少,加载因子是多少。扩容是怎么扩的

          1.8中,如果只是new ArrayList() ,容量其实是0,当第一次通过add(E e)时,才扩充为10

          扩容:

          ArrayList扩容的核心方法grow(),下面将针对三种情况对该方法进行解析:

          1,当前数组是由默认构造方法生成的空数组并且第一次添加数据。此时minCapacity等于默认的容量(10)那么根据下面逻辑可以看到最后数组的容量会从0扩容成10。而后的数组扩容才是按照当前容量的1.5倍进行扩容;

          2,当前数组是由自定义初始容量构造方法创建并且指定初始容量为0。此时minCapacity等于1那么根据下面逻辑可以看到最后数组的容量会从0变成1。这边可以看到一个严重的问题,一旦我们执行了初始容量为0,那么根据下面的算法前四次扩容每次都 +1,在第5次添加数据进行扩容的时候才是按照当前容量的1.5倍进行扩容。

          3,当扩容量(newCapacity)大于ArrayList数组定义的最大值后会调用hugeCapacity来进行判断。如果minCapacity已经大于Integer的最大值(溢出为负数)那么抛出OutOfMemoryError(内存溢出)否则的话根据与MAX_ARRAY_SIZE的比较情况确定是返回Integer最大值还是MAX_ARRAY_SIZE。这边也可以看到ArrayList允许的最大容量就是Integer的最大值(-2的31次方~2的31次方减1)。

          ArrayList:

            • 线程不安全,查询速度快
            • 底层数据结构是数组结构
            • 扩容增量:原容量的 0.5倍+1

            如 ArrayList的容量为10,一次扩容后是容量为16

            HashMap,默认大小是16,也就是支持存储最多20个键值对。如果不超过20个键值对,可以不设置,如果超出,按如下公式计算后设置:initialCapacity = (需要存储的元素(键值对)个数 / 负载因子) + 1。

            注意负载因子(即loader factor)默认为0.75

            HashMap

            网络异常,图片无法展示
            |
            image.gif 编辑

            5 waite sleep 区别

              • sleep()方法,属于Thread类中的。而wait()方法,则是属于Object类中的。
              • sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
              • 在调用sleep()方法的过程中,线程不会释放对象锁。
              • 而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备
              • sleep是Thread线程类的方法,而wait是Object顶级类的方法
              • sleep可以在任何地方使用,而wait只能在同步方法或者同步块中使用。

              其他问题:

                1. exception的父类是什么?
                2. hashmap是线程不安全的,如果要线程安全的用什么?
                3. 他的线程安全是如何实现的?
                4. 为什么分段和链表就线程安全了?
                5. spring aop原理?一般用在什么地方?
                6. jvm堆服务那几个代?
                7. 线程池thread pool有哪几个核心参数?
                8. 高并发情况下,数据库扛不住如何处理?
                9. 不用mq如何实现秒杀?



                相关文章
                |
                3月前
                |
                Java C++ 索引
                【Java】JavaSE基础知识
                【Java】JavaSE基础知识
                110 0
                |
                4月前
                |
                Java 编译器
                Java基础知识:什么是封装、继承和多态?
                Java基础知识:什么是封装、继承和多态?
                72 0
                |
                21天前
                |
                Java 程序员 调度
                Java中的多线程编程:基础知识与实践
                【4月更文挑战第5天】 在现代软件开发中,多线程编程是一个不可或缺的技术要素。它允许程序员编写能够并行处理多个任务的程序,从而充分利用多核处理器的计算能力,提高应用程序的性能。Java作为一种广泛使用的编程语言,提供了丰富的多线程编程支持。本文将介绍Java多线程编程的基础知识,并通过实例演示如何创建和管理线程,以及如何解决多线程环境中的常见问题。
                |
                2天前
                |
                IDE Java 开发工具
                Java从入门到精通:1.3.1实践编程巩固基础知识
                Java从入门到精通:1.3.1实践编程巩固基础知识
                |
                2天前
                |
                Java
                Java基础知识整理,驼峰规则、流程控制、自增自减
                在这一篇文章中我们总结了包括注释、关键字、运算符的Java基础知识点,今天继续来聊一聊命名规则(驼峰)、流程控制、自增自减。
                34 3
                |
                2天前
                |
                Java 开发者
                Java基础知识整理,注释、关键字、运算符
                在日常的工作中,总会遇到很多大段的代码,逻辑复杂,看得人云山雾绕,这时候若能言简意赅的加上注释,会让阅读者豁然开朗,这就是注释的魅力!
                37 11
                |
                27天前
                |
                关系型数据库 Java 开发工具
                Java入门高频考查基础知识9(15问万字参考答案)
                本文探讨了Spring Cloud的工作原理,包括注册中心的心跳机制、服务发现机制,以及Eureka默认的负载均衡策略。同时,概述了Spring Boot中常用的注解及其实现方式,并深入讨论了Spring事务的注解、回滚条件、传播性和隔离级别。文章还介绍了MySQL的存储引擎及其区别,特别关注了InnoDB如何实现MySQL的事务处理。此外,本文还详细探讨了MySQL索引,包括B+树的原理和设计索引的方法。最后,比较了Git和SVN的区别,并介绍了Git命令的底层原理及流程。
                32 0
                Java入门高频考查基础知识9(15问万字参考答案)
                |
                27天前
                |
                存储 缓存 算法
                Java入门高频考查基础知识4(字节跳动面试题18题2.5万字参考答案)
                最重要的是保持自信和冷静。提前准备,并对自己的知识和经验有自信,这样您就能在面试中展现出最佳的表现。祝您面试顺利!Java 是一种广泛使用的面向对象编程语言,在软件开发领域有着重要的地位。Java 提供了丰富的库和强大的特性,适用于多种应用场景,包括企业应用、移动应用、嵌入式系统等。下是几个面试技巧:复习核心概念、熟悉常见问题、编码实践、项目经验准备、注意优缺点、积极参与互动、准备好问题问对方和知其所以然等,多准备最好轻松能举一反三。
                55 0
                Java入门高频考查基础知识4(字节跳动面试题18题2.5万字参考答案)
                |
                27天前
                |
                存储 算法 JavaScript
                Java入门高频考查算法逻辑基础知识3-编程篇(超详细18题1.8万字参考编程实现)
                解决这类问题时,建议采取下面的步骤: 理解数学原理:确保你懂得基本的数学公式和法则,这对于制定解决方案至关重要。 优化算法:了解时间复杂度和空间复杂度,并寻找优化的机会。特别注意避免不必要的重复计算。 代码实践:多编写实践代码,并确保你的代码是高效、清晰且稳健的。 错误检查和测试:要为你的代码编写测试案例,测试标准的、边缘情况以及异常输入。 进行复杂问题简化:面对复杂的问题时,先尝试简化问题,然后逐步分析和解决。 沟通和解释:在编写代码的时候清晰地沟通你的思路,不仅要写出正确的代码,还要能向面试官解释你的
                33 0
                |
                27天前
                |
                存储 Java 编译器
                Java入门高频考查基础知识2(超详细28题2.5万字答案)
                多态是面向对象编程中的一个重要概念,它允许不同类的对象对同一消息作出不同的响应。在具体实现上,多态允许一个父类的引用指向其子类的对象,并根据实际指向的对象的类型来调用相应的方法。在 Java 中,多态可以通过以下几种方式实现:在同一个类中,方法名相同,但形参列表不同,实现了多态。子类可以重写(覆盖)其父类的方法,实现多态。在父类引用中调用该方法时,根据实际指向的子类对象的类型来调用相应的方法实现。
                40 0