Java知识补充

news2024/11/24 10:56:39

ArrayList

继承结构

在这里插入图片描述

为什么要先继承AbstractList,而让AbstractList先实现List?而不是让ArrayList直接实现List?

这里是有一个思想,接口中全都是抽象的方法,而抽象类中可以有抽象方法,还可以有具体的实现方法,正是利用了这一点,让AbstractList是实现接口中一些通用的方法,而具体的类,如ArrayList就继承这个AbstractList类,拿到一些通用的方法,然后自己在实现一些自己特有的方法,这样一来,让代码更简洁,就继承结构最底层的类中通用的方法都抽取出来,先一起实现了,减少重复代码。所以一般看到 一个类上面还有一个抽象类,应该就是这个作用。

ArrayList实现了哪些接口?

List接口:我们会出现这样一个疑问,在查看了ArrayList的父类 AbstractList也实现了List接口,那为什么子类ArrayList还是去实现一遍呢?

这是想不通的地方,查资料显示,有的人说是为了查看代码方便,使观看者一目了然,说法不 一,但每一个让我感觉合理的,但是在stackOverFlow中找到了答案,这其实是一个mistake,因为他写这代码的时候觉得这个会有用处,但是其实并没什么用,但因为没什么影响,就一直留到了现在。

RandomAccess接口:这个是一个标记性接口,通过查看api文档,它的作用就是用来快速随机存取, 有关效率的问题,在实现了该接口的话,那么使用普通的for循环来遍历,性能更高,例如ArrayList。而没有实现该接口的话,使用Iterator来迭代,这样性能更高,例如linkedList。所以这个标记性只是为了 让我们知道我们用什么样的方式去获取数据性能更好。

Cloneable接口:实现了该接口,就可以使用Object.Clone()方法了。

Serializable接口:实现该序列化接口,表明该类可以被序列化,什么是序列化?简单的说,就是能够 从类变成字节流传输,然后还能从字节流变成原来的类。

wait / sleep 的区别

1、来自不同的类

这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。

sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用了b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。

2、有没有释放锁(释放资源)

最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

sleep是线程被调用时,占着cpu去睡觉,其他线程不能占用cpu,os认为该线程正在工作,不会让出系统资源,wait是进入等待池等待,让出系统资源,其他线程可以占用cpu。

sleep(100L)是占用cpu,线程休眠100毫秒,其他进程不能再占用cpu资源,wait(100L)是进入等待池中等待,交出cpu等系统资源供其他进程使用,在这100毫秒中,该线程可以被其他线程notify,但不同的是其他在等待池中的线程不被notify不会出来,但这个线程在等待100毫秒后会自动进入就绪队列等待系统分配资源,换句话说,sleep(100)在100毫秒后肯定会运行,但wait在100毫秒后还有等待os调用分配资源,所以wait100的停止运行时间是不确定的,但至少是100毫秒。 就是说sleep有时间限制的就像闹钟一样到时候就叫了,而wait是无限期的除非用户主动notify。

3、使用范围不同

wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用

synchronized(x){
    //或者wait()
    x.notify()
}

4、是否需要捕获异常

sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

Executors

三大方法

Executors.newFixedThreadPool(int)

执行长期任务性能好,创建一个线程池,一池有N个固定的线程,有固定线程数的线程。

Executors.newSingleThreadExecutor()

只有一个线程

Executors.newCachedThreadPool()

执行很多短期异步任务,线程池根据需要创建新线程,但在先构建的线程可用时将重用他们。 可扩容,遇强则强

ThreadPoolExecutor

查看三大方法的调用源码,发现本质都是调用了 new ThreadPoolExecutor ( 7 大参数 )

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {

}

RejectedExecutionHandler 队列已满,而且任务量大于最大线程的异常处理策略

  • ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
  • ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
  • ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
  • ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

在这里插入图片描述
1、在创建了线程池后,开始等待请求。

2、当调用execute()方法添加一个请求任务时,线程池会做出如下判断:

  • 如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务
  • 如果正在运行的线程数量大于或等于corePoolSize,那么将这个任务放入队列
  • 如果这个时候队列满了且正在运行的线程数量还小于maximumPoolSize,那么还是要创建非 核心线程立刻运行这个任务
  • 如果队列满了且正在运行的线程数量大于或等于maximumPoolSize,那么线程池会启动饱和拒绝策略来执行。(最大容量为:maximumPoolSize + workQueue)

3、当一个线程完成任务时,它会从队列中取下一个任务来执行

4、 当一个线程无事可做超过一定的时间(keepAliveTime)时,线程会判断:

如果当前运行的线程数大于corePollSize,那么这个线程就被停掉。

所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。
在这里插入图片描述

  • CPU密集型程序线程数等于cpu数是最好
  • IO密集型线程数等于IO任务数是最佳的

Stream流式计算

Stream 自己不会存储元素

Stream 不会改变源对象,相反,他们会返回一个持有结果的新Stream。

Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
在这里插入图片描述

内部类

内部类分为四种:

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类

1.成员内部类

内部类访问外部类的所有属性(这里的属性包括私有的成员变量,方法)

public class Outer {
    private int id;
    public void out(){
        System.out.println("这是外部类方法");
    }
    
    class Inner{
        public void in(){
            System.out.println("这是内部类方法");
        }
        //内部类访问外部类私有的成员变量
        public void useId(){
            System.out.println(id+3);}
        //内部类访问外部类的方法
        public void useOut(){
            out();
        }
    }
}

public class Test{
    public static void main(String[] args) {
        //实例化成员内部类分两步
        //1、实例化外部类
        Outer outObject = new Outer();
        //2、通过外部类调用内部类
        Outer.Inner inObject = outObject.new Inner();
        //测试
        inObject.useId();//打印3,其中在内部类就使用了外部类的私有成员变量id。
        inObject.useOut();//打印:这是外部类方法
    }
}

如果内部类中的变量名和外部类的成员变量名一样,

public class Outer {

    private int id;//默认初始化0

    class Inner {
        private int id = 8; //这个id跟外部类的属性id名称一样。

        public void test() {
            System.out.println(id);//输出8,内部类中的变量会暂时将外部类的成员变量给隐藏
            // 如何调用外部类的成员变量呢?通过Outer.this
            System.out.println(Outer.this.id);//输出外部类的属性id。也就是输出0
        }
    }
}

借助成员内部类,来总结内部类(包括4种内部类)的通用用法:

  • 要想访问内部类中的内容,必须通过外部类对象来实例化内部类

  • 能够访问外部类所有的属性和方法,原理就是在通过外部类对象实例化内部类对象时,外部类对象把自己的引用传进了内部类,使内部类可以用通过Outer.this去调用外部类的属性和方法。一般都是隐式调用了,但是当内部类中有属性或者方法名和外部类中的属性或方法名相同的时候,就需要通过显式调用Outer.this了

2 静态内部类

  • static 一般只修饰变量和方法,平常不可以修饰类,但是内部类却可以被static修饰。

  • 我们上面说的内部类能够调用外部类的方法和属性,在静态内部类中就不行了,因为静态内部类没有了指向外部类对象的引用。除非外部类中的方法或者属性也是静态的。

  • 静态内部类可以包含静态成员,也可以包含非静态成员,但是在非静态内部类中不可以声明静态成员

  • 静态类内部不可以访问外部类的实例成员,只能访问外部类的类成员,即使是静态内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员

  • 外部类不可以定义为静态类,Java中静态类只有一种,那就是静态内部类,顶级类不能用static 修饰

  • 静态内部类能够直接被外部类给实例化,不需要使用外部类对象,Outer.Inner inner = new Outer.Inner();

3,局部内部类

局部内部类中可以访问外部类的成员变量及方法,局部内部类中如果要访问该内部类所在方法中的局部变量,那么这个局部变量就必须是final修饰的

  • 如果不实用final修饰,当局部内部类被实例化后,方法弹栈,局部变量随着跟着消失,这个时候局部内部类对象在想去调用该局部变量,就会报错,因为该局部变量已经没了,当局部变量用fanal修饰后,就会将其加入常量池中,即使方法弹栈了,该局部变量还在常量池中呆着,局部内部类也就是够调用
public class Outer {
    private int id;

    public void method01() {
        //这个就是局部变量cid。要让局部内部类使用,就得变为final并且赋值,如果不使用final修饰,就会报错
        final int cid = 3;
        class Inner {
            //内部类的第一个方法
            public void in() {
                System.out.println("这是局部内部类");
                //可以访问外部类的成员变量及方法
                System.out.println(id);
            }

            //内部类中的使用局部变量cid的方法
            public void useCid() {
                System.out.println(cid);
            }
        }
    }
}

局部内部类不能通过外部类对象直接实例化,而是在方法中实例化出自己来,然后通过内部类对象调用自己类中的方法。局部内部类只能在自己的方法中用,因为局部内部类相当于一个局部变量,出了方法就找不到了。

public class Outer {
    private int id;

    public void out() {
        System.out.println("外部类方法");
    }

    public void method01() {
        class Inner {
            public void in() {
                System.out.println("这是局部内部类");
            }
        }
        //在method01方法中自己创建内部类实例,然后调用内部类中的方法,等待外部类调用method01方法,就可以执行到内部类中的方法了。
        Inner In = new Inner();
        In.in();
    }
}

4 匿名内部类

在这四种内部类中,以后的工作可能遇到最多的是匿名内部类,如果一个对象只要使用一次,那么我们就是需要new Object().method()。 就可以了,而不需要给这个实例保存到该类型变量中去。这就是匿名对象。

匿名内部类需要依托于其他类或者接口来创建

  • 如果依托的是类,那么创建出来的匿名内部类就默认是这个类的子类
  • 如果依托的是接口,那么创建出来的匿名内部类就默认是这个接口的实现类。

匿名内部类的声明必须是在使用new关键字的时候

  • 匿名内部类的声明及创建对象必须一气呵成,并且之后能反复使用,因为没有名字

【不用匿名内部类】

public class Test {
    public static void main(String[] args) {
        // 如果我们需要使用接口中的方法,我们就需要走3步,
        // 1、实现接口 2、创建实现接口类的实例对象 3、通过对象调用方法
        //第二步
        Test02 test = new Test02();
        //第三步
        test.method();
    }
}

//接口Test1
interface Test01{
    public void method();
}

//第一步、实现Test01接口
class Test02 implements Test01{
    @Override
    public void method() {
        System.out.println("实现了Test接口的方法");
    }
}

【使用匿名内部类】

public class Test {
    public static void main(String[] args) {
        //如果我们需要使用接口中的方法,我们只需要走一步,就是使用匿名内部类,直接将其类的对象创建出来。
        new Test1(){
            public void method(){
                System.out.println("实现了Test接口的方法");
            }
        }.method();
    }
}

interface Test1{
    public void method();
}

Java中四大IO抽象类

InputStream、OutputStream和Reader、Writer类是所有IO流类的抽象父类

  • InputSteam是一个抽象类,它不可以实例化。 数据的读取需要由它的子类来实现。根据节点的不同,它派生了不同的节点流子类。继承自InputSteam的流都是用于向程序中输入数据,且数据的单位为字节
  • 字节流:以字节为单位获取数据,命名上以Stream结尾的流一般是字节流,如FileInputStream、FileOutputStream
  • Reader用于读取的字符流抽象类,数据单位为字符。
  • 字符流:以字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字符流,如FileReader、FileWriter。

分类之一:

  • 节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。
  • 处理流:不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流。
  • 节点流处于IO操作的第一线,所有操作必须通过它们进行;处理流可以对节点流进行包装,提高性能或提高程序的灵活性

Java 代理模式

静态代理

代码写死,静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的 class 文件

动态代理

  • 从 JVM 角度来说,动态代理是在运行时动态生成类字节码,并加载到 JVM 中的
  • 动态代理更加灵活。我们不需要针对每个目标类都单独创建一个代理类,并且也不需要我们必须实现接口
  • 实现方式
    • JDK
      • InvocationHandler 接口和 Proxy 类是核心
    • CGLIB
      • MethodInterceptor 接口和 Enhancer 类是核心

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/385650.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无聊小知识.03 Springboot starter配置自动提示

1、前言Springboot项目配置properties或yaml文件时候&#xff0c;会有很多spring相关的配置提示。这个是如何实现的&#xff1f;如果我们自己的配置属性&#xff0c;能否也自动提示&#xff1f;2、Springboot配置自动提示其实IDE是通过读取配置信息的元数据而实现自动提示的。S…

HCIE-Cloud Computing LAB备考第二步:逐题攻破--第一题:FusionCompute--合并小节

FusionCompute 三大要求&#xff1a;扩容对接共享存储windows版本的FC操作 FCWindows题目思维导图 扩容一台CNA节点&#xff0c;配置管理地址设置为&#xff1a;192.168.100.212。密码设置为&#xff1a;Cloud12#$。主机名设置为CNA2。【安装CNA 】【ctrlaltdel之后按esc选择…

双向链表+循环链表

循环链表双向链表 循环链表 循环链表是头尾相接的链表(即表中最后一个结点的指针域指向头结点&#xff0c;整个链表形成一个环)(circular linked list) **优点&#xff1a;**从表中任一结点出发均可访问全部结点 循环链表与单链表的主要差别当链表遍历时&#xff0c;判别当前…

精准测试对于覆盖率技术的全新诠释

对于白盒测试有深入研究的技术人员可能会问到&#xff0c;精准测试还是很多用到了覆盖率技术&#xff0c;这些本来不就是有开源的工具吗?下面我们来比较一下&#xff1a; 开源的覆盖率工具&#xff1a; 1、 将所有的测试产生的覆盖率混在一起&#xff0c;不具备快速定位缺陷与…

Pycharm补丁包使用教程

虽然社区版在大多情况下已经够用&#xff0c;但是有很多功能都是没有的&#xff0c;对照起一些教程之类的就很不方便 现在直接教一种简单中的简单的补丁包使用方法 我这里用的是 pycharm 19.2.6 注意右下角的configure 一般别的方法都是 打开&#xff0c;然后添加路径&#…

关于提高PX4抗风性

滚转角速率控制器&#xff1a;&#xff08;MC_ROLLRATE_P&#xff0c; MC_ROLLRATE_I&#xff0c; MC_ROLLRATE_D&#xff09; 滚转角速率控制器&#xff1a;&#xff08;MC_PITCHRATE_P&#xff0c; MC_PITCHRATE_I&#xff0c;MC_PITCHRATE_D&#xff09; 滚转角速率控制器…

php宝塔搭建部署实战CSM会议室预约系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套基于fastadmin开发的CSM会议室预约系统的源码。感兴趣的朋友可以自行下载学习。 技术架构 PHP7.2 nginx mysql5.7 JS CSS HTMLcnetos7以上 宝塔面板 文字搭建教程 下载源码&#xff0…

5年软测,女朋友跑了俩,2年外包感觉自己废了一半,怎么办?

17年毕业&#xff0c;校招毕业就进入一家软件公司&#xff0c;干了2年的点工&#xff0c;随后进入一家外包公司工作至今&#xff0c;安逸使人堕落不知进取&#xff0c;加之随着近年的环境不景气&#xff0c;谈了多年将要结婚的女朋友也因为我的心态和工资要跟我闹分手我想改变现…

nodejs安装和卸载超详细步骤

安装程序①下载完成后&#xff0c;双击安装包&#xff0c;开始安装&#xff0c;使用默认配置安装一直点next即可&#xff0c;安装路径默认在C:\Program Files下&#xff0c;也可以自定义修改②安装路径默认在C:\Program Files下面&#xff0c;也能够自定义修改&#xff0c;而后…

力扣-2020年最后一次登录

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1890. 2020年最后一次登录二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.…

ThreadLocal学会了这些,你也能和面试官扯皮了!

前言 我们都知道,在多线程环境下访问同一个共享变量,可能会出现线程安全的问题,为了保证线程安全,我们往往会在访问这个共享 变量的时候加锁,以达到同步的效果,如下图所示。 对共享变量加锁虽然能够保证线程的安全,但是却增加了开发人员对锁的使用技能,如果锁使用不当…

MySql主键id不推荐使用UUID

前言 昨天在某个技术群中&#xff0c;有个老哥发送了一个技术视频&#xff1a;讲的是一个毕业生面试被问&#xff0c;前后端的交互ID是使用自增的吗&#xff1f;为什么不使用UUID&#xff1f;最后的解释是说性能问题&#xff0c;这个引起了我的兴趣&#xff0c;查了一下资料总…

计算机网络安全基础知识4:命令执行漏洞,危害极大,DVWA演示命令注入漏洞攻击网站,防御命令注入执行漏洞,low,medium,high,impossible

计算机网络安全基础知识4&#xff1a;命令执行漏洞&#xff0c;危害极大&#xff0c;DVWA演示命令注入漏洞攻击网站&#xff0c;防御命令注入执行漏洞&#xff0c;low&#xff0c;medium&#xff0c;high&#xff0c;impossible 2022找工作是学历、能力和运气的超强结合体&…

CHAPTER 3 Web HA集群部署 - RHCS

Web HA集群部署 - RHCS1. RHCS介绍2. RHCS的核心功能2.1 负载均衡2.2 高可用2.3 存储3. RHCS集群的组成部分3.1 集群管理器CMAN3.2 资源组管理器rgmanager3.3 集群配置文件管理CCS3.4 保护设备Fencs3.5 分布式锁管理器DLM3.6 集群文件系统GFS3.7 集群配置管理工具Conga4. RHCS历…

白盒测试复习重点

白盒测试白盒测试之逻辑覆盖法逻辑覆盖用例设计方法1.语句覆盖2.判定覆盖(分支覆盖)3.条件覆盖4.判定条件覆盖5.条件组合覆盖6.路径覆盖白盒测试之基本路径测试法基本路径测试方法的步骤1.根据程序流程图画控制流图2.计算圈复杂度3.导出测试用例4.准备测试用例5.例题白盒测试总…

扬帆优配“机器人+”方案加码产业发展,这些股有望高增长

“机器人”发明新需求&#xff0c;2022年中国机器人市场规模约为174亿美元。 美国时刻3月1日&#xff0c;特斯拉在得克萨斯州超级工厂举办投资者日活动&#xff0c;展示了人形机器人Optimus的视频&#xff0c;更夸大的是&#xff0c;视频中的机器人好像在制作另一个机器人&…

更改linux时区、时间

问题描述&#xff1a; MINIO上传失败&#xff0c;错误信息如下&#xff1a; The difference between the request time and the servers time is too large. 原因分析&#xff1a; 系统时区与硬件时区不一致导致的 解决方案&#xff1a; 第一种情况&#xff0c;Time zone时区…

【大数据监控】Prometheus、Node_exporter、Graphite_exporter安装部署详细文档

目录Prometheus简介下载软件包安装部署创建用户创建Systemd服务修改配置文件prometheus.yml启动Prometheusnode exporter下载软件包安装部署添加用户创建systemd服务启动node_exportergraphite_exporter下载软件包安装部署创建systemd服务启动 graphite_exporterPrometheus 简介…

rsync+xinetd+inotify+sersync

一、介绍 1.1、rsync 对比 scp 相同&#xff1a; 都有拷贝的功能不同&#xff1a; rsync:具有增量复制&#xff0c;每次复制的时候&#xff0c;会扫描对端是否在同路径下有我要发送的一样的文件或者目录&#xff0c;如果&#xff0c;如果存在&#xff0c;则不进行复制。边复制&…

【脚本】用于得到某个文件/文件夹所有文件的存储大小(MB单位)

知识点 来自在线转换换算网页&#xff1a;在线文件大小(bit,bytes,KB,MB,GB,TB)转换换算 电脑中存储常用的单位&#xff1a; 1Byte(Byte 字节) 8Bit 1KB (Kilobyte 千字节) 1024Byte 1MB (Megabyte&#xff0c;兆字节&#xff0c;简称“兆”) 1024KB 1GB (Gigabyte&am…