面试题积累/Java基础/多线程/数据结构/spring

3 篇文章 0 订阅
2 篇文章 0 订阅

1:ArrayList和LinkedList的区别是什么?

共同点:实现了List的接口(都是list接口的实现类)

不同点:
ArrayList底层是数组 数据多的情况下:根据索引访问元素比较快
LinkedList底层是双向列表 数据多的情况下:插入,添加,删除比较快

2:高并发中的线程集合有哪些问题?
第一代是线程安全集合类
vector hashTable
默认是线程安全的
效率低:因为使用了synchronized修饰方法
第二代线程非安全集合类
ArrayList HashMap
线程不安全但是性能好
解决办法:底层继续启用了synchronized代码块锁以保证安全性
第三代线程安全集合类
启用新类(以后了解)
底层大都采用Lock锁,保证安全性能高

3: jdk1.8新特性有哪些?
1:接口有了新的默认方法,是非抽象的方法
2:lambda表达式
3:支持多重注解

4:Cookie 和session的区别
从定义上:当浏览器访问服务器的servlet,
servlet会保存用户提交的信息,例如购买一顶帽子
关于帽子的信息会被加到表头信息,传到浏览器本地保存到cookie下来

      而session则不同,session是servlet在会话域开辟出来的一块内存,
      用来保存这次访问服务器的信息,例如提交一件外套的信息

从保存
地点来看 Cookie:
当浏览器下次访问服务器时,这些保存的本地信息会重新加到表头信息重新发给服务器
这样的话存取都会发生在本地的一个浏览器

     session:
   	当下次再次访问服务器时,浏览器能拿到session保存的信息
    	这些信息都是服务端产生和保存的

从保存限制
来看: Cookie在浏览器最多保存几十个,每个cookie不超过4k字节

从安全角度:
Cookie由于存放在浏览器容易被修改,造成Cookie欺骗的后果
session则比较安全保存在服务器而且

      怎么区分不同客户端对应的session?
      当第一次访问时会保存下来一个sessionId保存在浏览器,
      当第二次访问时,浏览器会带着这个sessionId去服务器找对应的session

5、String 与StringBuffer的共同点与不同点
a.共同点
String 与stringBuffer 都是charsequence的实现类。
string 与stringBuffer 都由final所修饰(不可被继承)。

它们底层的数据源都是char[]数组。

它们共同具有“字符序列”处理的功能特征。

从本质上讲,其实是不可变的静态数据与可变的动态数据的区别。
b.不同点
(1)-数组引用的指向
String底层的char数组声明为final,该char数组属性不可被修改。 private final char value[];
(虽然比较安全,即不能实现数组裁剪与扩容,只会一直创建新对象,从而导致性能低下,

Stringbuilder继承abstractStringBuilderd但是底层char数组没有final修饰,char[] value;比较不安全
StringBuilder修改的是原字符窜,返回的还是自身对象,但是为了安全考虑,后面提出stringBuffer

StringBuffer跟StringBuilder 是对好兄弟都是AbstractStringBuilder的徒弟。都继承了老AbstrctStringBuilder
(可以对数组的进行裁剪与扩容,但是StringBuffer操作字符窜时都会加SynChronized锁,性能比Builder低)
c.不同点
(2)处理字符的方式
String 可以通过加法(+)运算符或其内部方法来处理字符串,并且生成的是新的对象,需要重新赋值给变量来接收数据。
StringBuffer 只能通过其内部方法来处理字符串,但它是对自身的内容进行修改而不生成新的对象,不用再赋值给变量。
d.不同点
(3)-性能比较
String通过新建一个String对象的方式来达到使用新数据的目的性能较差,每做调用一次字符串操作方法都新建对象。
e.不同点
(4)-final修饰后的效果String的变量给final修饰后,则无法再接收新的数据。
StringBuffer的变量给final修饰后,仍可以修改数据。
f.不同点
(5)-创建方式
String可以直接通过常量赋值。
StringBuffer 需要创建才可以使用。

6、线程的含义:
线程通俗得说是程序的不同的执行路线
专业得说:
程序是可执行文件放在磁盘,但其被单击时,被操作系统送入内存,编译后的指令和数据移至cpu
指令放入计数器,数据放入寄存器。

7:synchronized与Lock的区别

1、内部锁机制与API锁实现
synchronized是在JVm层面的,所以synchronized是java的关键字,底层是monitor对象,可以修饰方法也可以修饰代码块
而lock是api层面的,它是一个具体的类。

2、自动与手动解锁
synchronized 不需要用户手动地去释放锁,当synchronized代码执行完毕之后或者代码出现异常系统会自动让线程释放锁
而ReentrantLock需要用户手动的释放锁,如果用户没有主动的释放锁,那么就有可能出现死锁的问题。
具体来说,需要使用lock()方法,和unlock()方法,配合try,finally语句块来完成。

3、中断锁机制
synchronized不可以中断,除了非正常运行或者抛出异常。
ReentrantLock可以中断的
1、设置超时的方法tryLock(longtimeout,TimeUnit unit)
2、1ockInterruptib1y()放在代码块中,调用interrupt()方法可中断

4、公平与非公平
synchronized是不公平锁,就是不管有多少线程在排队等待锁,都会去竞争一次锁,
synchronized默认是非公平锁,但是可以通过往构造方法中传入boolean来选择是使用公平锁,还是非公平锁
lock

5、多条件唤醒与精确唤醒
lock锁可以绑定多个条件condition,但是synchronized是不可以的,synchronized唤醒锁的时候要么全部唤醒notify,要么唤醒一个线程notifyA11。但是使用1ock可以精确唤醒想要唤醒的线程signal。

6、上锁与解锁次数
synchronized是Jvg内部锁机制,不用人为干预上锁解锁,所以无须理会解锁的次数的问题。

1ock内部使用锁计数的方式来记录上锁的次数,所以,要注意解锁次数,解锁时解锁的次数要与上锁次数相等方能解锁。

7、锁等候机制与锁试探
Lock 可以在一定时间内尝试获取锁,时间一过放弃获取锁。
lock.tryLock(传入时间);Lock获取锁前,可以试探锁状态是否被占用,如果被占用,则放弃获取锁。
lock.tryLock();

8、什么是线程池
线程池(Thread Poo1)是一种基于池化思想设计出来的线程生产与管理的工具,它也是一个线程工厂与线程容器,用于存储一定量的线程,以应付系统并发执行任务的需求。
当程序需要使用线程来执行任务时,程序可从线程池中获取一个空闲线程来执行任务,任务结束后,该线程不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务(或由线程池来决定下一步的处理)。

9.线程池的使用目的?
1.降低资源消耗
通过重复利用已创建的线程降低线程创建和销毁所带来的消耗。
2.提高响应速度
当任务到达时,任务不需要的等待线程的创建,即可立即执行任务。
3.提高线程的可管理性
如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的线程资源分配,调优和监控。
总结:
线程复用,控制最大并发数,管理与维护线程,协调与合理地调度资源,在高并发场景下减少系统开销,提升系统性能。
可以通过设置参数,以适配不同的并发应用场景。

10、常见的线程池
.FixedThreadPool
.CachedThreadpool
.scheduledThreadPool
.SingleThreadExecutor

.FixedThreadPool:固定线程池
它的核心线程数和最大线程数是一样的,所以可以把它看作是固定线程数的线程池,它的特点是线程池中的线程数除了初始阶段需要从0开始增加外,之后的线程数量就是固定的,就算任务数超过线程数,线程池也不会再创建更多的线程来处理任务,而是会把超出线程处理能力的任务放到任务队列中进行等待。
而且就算任务队列满了,到了本该继续增加线程数的时候,由于它的最大线程数和核心线程数是一样的,所以也无法再增加新的线程。

.CachedThreadpool:可缓存线程池
它的特点在于线程数是几乎可以无限增加的(实际最大可以达到Integer.MAX_VALUE,为2~31-1,这个数非常大,所以基本不可能达到到,而当线程闲置时还可以对线程进行回收。
也就是说该线程池的线程数量不是固定不变的,当然它也有一个用于存储提交任务的队列,但这个队列是synchronousQueue,队列的容量为0,实际不存储任何任务,它只负责对任务进行中转和传递,所以效率比较高。
当我们提交一个任务后,线程池会判断己创建的线程中是否有空闲线程,如果有空闲线程则将任务直接指派给空闲线程,如果没有空闲线程,则新建线程去执行任务,这样就做到了动态地新增线程。

ScheduledThreadPool:周期性任务线程池
它支持定时或周期性执行任务。比如每隔10秒钟执行一次任务

SingleThreadExecutor:单线程线程池
它使用唯一的线程去执行任务,原理和FixedThreadPool一样,只不过这里线程只有一个,如果线程在执行任务的过程中发生异常,线程池也会重新创建一个线程来执行后续的任务。

这种线程池由于只有一个线程,所以非常适合用于所有任务都需要按被提交的顺序依次执行的场景,而前几种线程池不一定能够保亲任务的执行顺序等于被提交的顺序,因为它们是多线程并行执行

11、Integer和int的区别
1:Integer 是int这个基本数据类型的封装类,
int直接声明变量赋值就可以了,但是Inteder需要new对象再去赋值

2:基本数据类型和Integer混合使时,java会自 动通过拆箱和装箱来实现类型转换

3:integer作为int的封装类,封装了一些属性和方法 ,是一个对象存储在堆内存里
而int 是基本数据类型直接存储在栈空间里

4:integer默认值是null,int默认是0

12、SpringFrameWork的@conditional注解有什么作用?
1:作用:
@conditional作用是给需要装载的bean增加条件判断,
只有满足条件的bean才能装载到IOC容器里

2:通过实现condition这个接口,
再去重写matches方法,来自定义bean装载的条件 返回true才可以装载进去

12、类加载
一个java程序的从源文件到最终运行,必须要经过编译和类加载两个阶段。
编译的过程就是java编译器把.java文件编译成.class文件。
类加载的过程,就是类加载器去文件管理系统把.class文件装载到JvM内存中,装载完成以后就会得到一个class对象,我们就可以使用new关键字来实例化这个对象。

而类的加载过程,需要涉及到类加载器。
JVM在运行的时候,会产生3个类加载器,这三个类加载器组成了一个层级关系每个类加载器分别去加载不同作用范围的jar包。
比如:
Bootstrap ClassLoader(启动/引导类加载器)
主要是负责Java核心类库的加载,也就是%(JDK_HOME\1ib下的rt.jar、resources.jar等。
Extension ClassLoader(扩展类加载器)主要负责%(DK_HoME)\lib\ext目录下的jar包和class文件

Application classLoader(应用程序类加载器)主要负责当前应用里面的classpath下的所有jar包和类文件。
另外,除了系统自己提供的类加载器以外,还可以通过classLoader类实现自定义加载器,去满足一些特殊场景的需求。

13、双亲委派机制:
就是按照类加载器的层级关系,逐层进行委派。
比如:当需要加载一个class文件的时候,首先会把这个class的查询和加载委派给父类加载器去执行,如果父加载器都无法加载,再尝试自己来加载这个class。

14、双亲委派机制存在的意义(向上委托类加载,避免重复加载,还有避免被恶意篡改)
1.通过委派的方式,可以避免类的重复加载,当父加载器已经加载过某一个类时,子加载器就不会再重新加载这个类。
2.通过双亲委派的方式,还保证了安全性。因为Bootstrap classroader在加载的时候,只会加载JAVAHOME中的jar包里面的类。
如:java.lang.Integer,java.lang.string 等,那么这个类是不会被随意替换的,除非有人跑到你的机器上,破坏你的JDK。
那么,就可以避免有人自定义一个有破坏功能的java.lang.Integer被加载。
这样可以有效的防止核心avaApI被篡改。
双亲委派机制是在classLoader里的loadclass方法里实现的。

15、实现流程:
1.首先判断该类是否已经被加载
2.该类未被加载,如果父类不为空,交给父类加载
3.如果父类为空,交给bootstrap classloader加载
4.如果类还是无法被加载到,则触发findclass,抛出classNotFoundException(findclass这个方法当前只有一个语句,就会抛出classNotFoundException),如果想自己实现类加载器的话,可以继承classLoader后重写findclass方法,加载对应的类)
破坏双亲委派机制
双亲委派机制有它存在的意义,不过也存在许多场景是需要破坏这个机制的,所以双亲委派机制也非必然。

16、Tomcat的类加载机制
比如:Tomcat web容器里面部署了很多的应用程序,但是这些应用程序对于第三方类库的依赖版本却不一样,但这些第三方类库的路径又是一样的,如果采用默认的双亲委派类加载机制,那么是无法加载多个相同的类。
所以,tomcat破坏双亲委派原则,提供隔离的机制,为每个web容器单独提供一个WebAppC1assLoader 加载器。
为了实现隔离性,优先加载Web应用自己定义的类,所以没有遵照双亲委派的约定,每一个应用都有自己的类加载器WebappClassLoader负责加载本身的目录下的class文件,加载不到时再交给commonclassLoader加载,这和双亲委派刚好相反。

17、你对synchronized了解不,能否介绍下你对synchronized的理解?
synchronized中文意思是同步,也称之为同步锁。主要是为了解决线程安全的问题而使用,
synchronized的作用是保证在同一时刻,被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果。

应用位置
通常用应在同步普通方法、静态方法、代码块中。
修饰实例方法:作用于当前实例加锁
修饰静态方法:作用于当前类对象加锁
修饰代码块:指定加锁对象,对给定对象加锁

synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。
在JDK1.5之前synchronized是一个重量级锁,相对于Lock,它会显得比较笨重。(效率低)

原因如下:
因为监视器锁(monitor)是依赖于底层的操作系统的 Mutex Lock来实现的,Java的线程是映射到操作系统的原生线程之上的。如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高,这也是为什么早期的synchronized效率低的原因。
Javal.6对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。
使得synchronized在一些情况下并不是一把重量级的锁,而是一个很轻的一把锁。

18、synchronized的作用主要有三个:
原子性:确保线程互斥地访问同步代码;可见性:保证共享变量的修改能够及时可见,其实是通过Java内存模型中的“对一个变量unlock操作之前,必须要同步到主内存中;如果对一个变量进行1ock操作,则将会清空工作内存中此变量的值,在执行引擎使用此变量前,需要重新从主内存中1oad操作或assign 操作初始化变量值”来保证的:
有序性:有效解决重排序问题,即一个unlock操作先行发生(happen-before)于后面对同一个锁的1ock操作”;

19、Spring 是什么?
Spring是一个轻量级的IoC和A0P容器框架。
为了解决什么?
为了解决在项目开发与后期扩展过程中,模块间解耦问题。
使用项目在后期扩展与维护时,组件功能替换,组件升级的更为简单。
并在运行过程中,实现对象的创建,依赖对象的查找与注入。并对项目中的组件统一管理与实现对象的复用,有利于系统功能模块的分层设计。

20、Spring 设计目标:
为Java应用程序提供基础性服务的一套框架。
Spring为开发者提供一个一站式轻量级应用开发平台。
简化企业应用程序的开发,让开发者有更多时间关心系统业务需求设计。

21:Spring 设计理念:
在JavaEE开发中,支持poJ0和JavaBean开发方式,使应用面向接口开发,充分支持o0(面向对象)设计方法;Spring通过IoC容器实现对象耦合关系的管理,将对象之间的依赖关系交给IoC容器,实现解耦;

22:Spring 框架的核心:
IoC容器和A0P模块。通过Ioc容器管理POJ0对象以及他们之间的耦合关系;通过AOP以动态非侵入的方式增强服务。
Ioc让相互协作的组件保持松散的耦合,而AoP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。

23、主要包括以下七个模块:
Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);Spring Core:核心类库,所有功能都依赖于该类库,提供rOC和D工服务;Spring AoP:AoP服务;Spring Web:提供了基本的面向Web的综合特性,提供对常见框架如struts2的支持,Spring 能够管理这些框架,将Spring的资源注入给框架,也能在这些框架的前后插入拦截器;Spring MWC:提供面向Web应用的Model-View-Controller,即MvC 实现。
Spring DA0:对JDBC的抽象封装,简化了数据访问异常的处理,并能统一管理JDBC事务;Spring oRM:对现有的ORM框架的支持;

24、Spring的优点?
(1)spring属于低侵入式设计,代码的污染极低;
(2)spring的DI机制将对象之间的依赖关系交由框架处理,减低组件的耦合性;
(3)Spring提供了AOP技术,支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,从而提供更好的复用。
(4)spring对于主流的应用框架提供了集成支持。

25:线程安全的理解
线程安全也可以叫内存安全
因为线程会去访问内存,是否能得到正确的结果就是线程安全也叫作内存安全

因为堆是所有线程共享的就是都可以访问的
多线程去访问堆内存时要得到一个正确的对象才行,如果不能保证这一点那就是
线程不安全的

26:守护线程的理解
守护线程是服务所有线程的保姆
所有用户线程结束守护线程才结束,但它的终止是不确定的,随时停止

应用场景:
1:可以为所有用户线程提供服务
2:要正常结束并且不能产生异常

27:
索引
什么是索引?
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。
更通俗的说,索引就相当于目录。为了方便查找书的内容,通过对内容建立索引形成目录。索引是一个文件,它是要占据物理空间的。

28:索引有哪几种类型?
主键素引:数据列不允许重复,不允许为NULL,一个表只能有一个主键。
唯一索引:数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。
·可以通过ALTERTABLEtable_nameADDUNIQUE(column);创建唯一索引
·可以通过ALTERTABLEtable_nameADDUNIQUE(column1,column2;创建唯一组合索引
普通索引:基本的索引类型,没有唯一性的限制,允许为NULL值。

·可以通过ALTERTABLEtable_nameADDINDEXindex_name(column);创建普通索引
·可以通过ALTERTABLEtable_nameADDINDEXindex_name(column1.column2.column3);创建组合素引
·全文索引:是目前搜索引擎使用的一种关键技术。
可以通过ALTERTABLEtable_nameADDFULLTEXT(column);创建全文索引

29:
索引的数据结构(b树,hash)
索引的数据结构和具体存储引擎的实现有关,在MySQL中使用较多的素引有Hash索引,B+树素引等,
而我们经常使用的InnoDB存储引擎的默认索引实现为:B+树素引。对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能快;其余大部分场景,建议选择BTree索引。
1)B树索引mysql通过存储引擎取数据,基本上90%的人用的就是InnoDB了,按照实现方式分,InnoDB的索引类型目前只有两种:BTREE(B树)索引和HASH索引。B树索引是Mysq数据库中使用频繁的索引类型,基本所有存储引擎都支持BTree索引。
通常我们说的索引不出意外指的就是(B树)索引(实际是用B+树实现的,因为在查看表索引时,mysql一律打印BTREE,所以简称为B树索引)

30:索引查询方式:
主键索引区:P(关联保存的时数据的地址)按主键查询,
普通索引区:si(关联的id的地址,然后再到达上面的地址)。所以按主键查询,速度快
B+tree性质:
1.)n棵子tree的节点包含n个关键字,不用来保存数据而是保存数据的索引。
2.)所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。

3.)所有的非终端结点可以看成是索引部分,结点中仅含其子树中的大(或小)关键字。
4.)B+树中,数据对象的插入和删除仅在叶节点上进行。
5.)B+树有2个头指针,一个是树的根节点,一个是小关键码的叶节点。2)哈希索引简要说下,类似于数据结构中简单实现的HASH表(散列表)一样,当我们在mysql中用哈希索引时,主要就是通过Hash算法(常见的Hash算法有直接定址法、平方取中法、折叠法、除数取余法、随机数法),将数据库字段数据转换成定长的Hash值,与这条数据的行指针一并存入Hash表的对应位置;如果发生
Hash碰撞(两个不同关键字的Hash值相同),则在对应Hash键下以链表形式存储。

31:索引的基本原理
索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。
索引的原理很简单,就是把无序的数据变成有序的查询
1.把创建了索引的列的内容进行排序
2.对排序结果生成倒排表
3.在倒排表内容上拼上数据地址链
4.在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据

32:一、SpringMVC但架
SpringMVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将Web层进行职责解耦,把复杂的Web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。
简而言之,SpringMVc就是将我们原来开发在Servlet中的代码拆分了,一部分由SpringMVC完成,一部分由我们自己完成。

33、SpringMVC工作流程
1.用户发送请求到前端控制器(Dispatcherservlet)。
2.前端控制器收到请求后,调用处理器映射器(HandlerMapping),去查找处理器(Handler)。
3.处理器映射器解析出请求的URI,并根据xml配置或注解进行查找与URI相匹配的映射规则的控制器或拦截器,并存入到一个执行链当中,然后,返回给Dispatcherservlet 前端控制器。
4.前端控制器调用处理器适配器(HandlerAdapter)。
5.在调用HandlerAdapter过程中,会执行一系列的数据转换,数据校验,数据格式化,数据绑定到参数的一系列流程。
6.处理器适配器调用自定义的处理器类(Controller)。
7.自定义的处理器类将得到的参数进行请求处理,并返回结果给处理器适配器(HandlerAdapter)。
8.处理器适配器(HandlerAdapter)将得到的结果返回给前端控制器
(DispatcherServlet)。
9.前端控制器将ModelAndView 传给视图解析器 ViewReslover。
10.视图解析器将ModelAndView对象从逻辑视图转换为物理视图,并将ModelAndView中携带的模型数据,设置进View对象,并返回给前端控制器。
11.前端控制器调用物理视图的render渲染方法,以sp为例,reder方法会将模型数据,转存到请求域,然后,又再次交给Tomcat中的JspServlet 将请求域中数据填充到sp页中EL达式中,再最终生成出静态页面。
12.最终,将静态页面的全部数据发送至客户端。
(完成整个请求的流程)

34、如果在拦截请求中,我想拦截get方式提交的方法,怎么配置?
可以在QRecquestMapping 注解里面加上method=RequestMethod.GET或直接使用eGetMapping;

35、如何使用注解设置一个自定义类为控制器。
1.在类上使用@controller,Dispatcherservlet 在启动时一旦扫描到这个注解会将其实例化到容器,配合标记了@RequestMapping 注解的方法,此控制器则具有控制器的处理请求能力。
2.在类上使用@Component+@RequestMapping 注解,@Component使其I能被实例化到容器,@RequestMapping 声明类级别的映射地址。以及在方法上使用@RequestMapping注解,设置方法级别映射地址。
一旦扫描到类上的eRequestMapping 注解,也会将此类处理为一个控制器类。
3.在类上使用econtroller+eRequestMapping 注解,以及在方法上使用QRequestMapping 注解。

36、怎么样把ModelMap 里面的数据放入Session里面?
可以在类上面加上asessionAttributes 注解,里面包含的ModelMap中存放数据的KEY值,SpringMVC在处理时,会将ModelMap中对应的键值对存入session。

37:为什么重写equals方法时要重写hashCode方法Java设计的顶级父类0bject类中,有两个方法很特殊,它们分别是equals方法与hashCode方法。一旦重写了equals方法,就一定要重写hashCode方法。如果一个类没有重写equals(Object obj)方法,则等价于通过=比较两个对象,即比较的是对象在内存中的空间地址是否相等;如果重写了equals(Object obj)
方法,则根据重写的方法内容去比较相等,返回true则相等,false则不相等。

38:讲一讲内存泄露?>
多线程的内存泄漏分为两个方面:
是多线程Threadlocal底层是ThreadMap,
而threadMap是由entry类实现的,它是key-value结构
而多线程的内存泄漏就是因为一方面key造成第二是value造成
key造成是因为如果线程还继续在内存中运行,那么当垃圾回收时,根据stw可达通原则
如果此时key是强引用不能回收key这个变量,所以我们最后是采用弱引用来解决的
还有一个是value造成的,因我们是用线程执行结束时,启用一个remove方法对value进行删除.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值