java基础知识——高频

String,Stringbuffer,StringBuilder的区别

String:

String类是一个不可变的类,一旦创建就不可以修改。
String是final类,不能被继承
String实现了equals()方法和hashCode()方法
StringBuffer:

继承自AbstractStringBuilder,是可变类。
StringBuffer是线程安全的
可以通过append方法动态构造数据。
StringBuilder:

继承自AbstractStringBuilder,是可变类。

StringBuilder是非线性安全的。

执行效率比StringBuffer高。

作者:希望秋招拿到offer

链接:https://www.nowcoder.com/discuss/452732
来源:牛客网

反射的原理,反射创建类实例的三种方式是什么

Java反射机制:

​ Java 的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法; 并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制

获取 Class 类对象三种方式:

使用 Class.forName 静态方法
使用类的.class 方法
使用实例对象的 getClass() 方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
写出读入
在这里插入图片描述

作者:希望秋招拿到offer

链接:https://www.nowcoder.com/discuss/452732
来源:牛客网

谈谈序列化与反序列化

序列化是指将对象转换为字节序列的过程,而反序列化则是将字节序列转换为对象的过程。
Java对象序列化是将实现了Serializable接口的对象转换成一个字节序列,能够通过网络传输、文件存储等方式传输 ,传输过程中却不必担心数据在不同机器、不同环境下发生改变,也不必关心字节的顺序或其他任何细节,并能够在以后将这个字节序列完全恢复为原来的对象。

SQL注入

SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
1)SQL注入攻击的总体思路

​ ●寻找到SQL注入的位置
​ ●判断服务器类型和后台数据库类型
​ ●针对不同的服务器和数据库特点进行SQL注入攻击

请你说明一下 left join 和 right join 的区别?

left join(左联接) :返回包括左表中的所有记录和右表中联结字段相等的记录
right join(右联接) :返回包括右表中的所有记录和左表中联结字段相等的记录

事务是什么

​ 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

作者:希望秋招拿到offer
链接:https://www.nowcoder.com/discuss/452732
来源:牛客网

数据库ACID的特性。

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性指事务前后数据的完整性必须保持一致。

隔离性指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离。

持久性是指一个事务一旦提交,它对数据库中数据的改变就是永久性的,即便数据库发生故障也不应该对其有任何影响。

作者:希望秋招拿到offer
链接:https://www.nowcoder.com/discuss/452732
来源:牛客网

请你介绍一下,数据库的三个范式?

第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。

第二范式(2NF):首先满足 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。

第三范式(3NF):首先是满足2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况

作者:希望秋招拿到offer
链接:https://www.nowcoder.com/discuss/452732
来源:牛客网

请你介绍一下数据库的隔离级别

隔离级别 脏读 不可重复读 幻读
未提交读 可能 可能 可能
已提交读 不可能 可能 可能
可重复读 不可能 不可能 可能
可串行化 不可能 不可能 不可能
作者:希望秋招拿到offer
链接:https://www.nowcoder.com/discuss/452732
来源:牛客网

未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据。

已提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)。

可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读。

串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。

作者:希望秋招拿到offer
链接:https://www.nowcoder.com/discuss/452732
来源:牛客网

数据库的脏读、幻读、不可重复读

1.脏读:

指一个事务A正在访问数据,并且对该数据进行了修改,但是这种修改还没有提交到数据库中(也可能因为某些原因Rollback了)。这时候另外一个事务B也访问这个数据,然后使用了这个被A修改的数据,那么这个数据就是脏的,并不是数据库中真实的数据。这就被称作脏读。(事务A读到了事务B未提交的数据)

解决办法:把数据库事务隔离级别调整到 READ_COMMITTED

即让用户在更新时锁定数据库,阻止其他用户读取,直到更新全部完成才让你读取。

2.幻读:

指一个事务A对一个表中的数据进行了修改,而且该修改涉及到表中所有的数据行;同时另一个事务B也在修改表中的数据,该修改是向表中插入一行新数据。那么经过这一番操作之后,操作事务A的用户就会发现表中还有没修改的数据行,就像发生了幻觉一样。这就被称作幻读。(事务A修改数据,事务B插入数据,A发现表中还没有修改的数据行)

解决办法:把数据库事务隔离级别调整到 SERIALIZABLE_READ

3.不可重复读:

指在一个事务A内,多次读同一个数据,但是事务A没有结束时,另外一个事务B也访问该同一数据。那么在事务A的两次读数据之间,由于事务B的修改导致事务A两次读到的数据可能是不一样的。这就发生了在一个事务内两次读到的数据不一样,这就被称作不可重复读。(事务A多次读数据,事务B访问数据,A读到了B修改的数据,导致两次读到的数据不一样)

解决办法:把数据库事务隔离级别调整到REPEATABLE_READ

级别高低:脏读 < 不可重复读 < 幻读

所以设置了最高级别的SERIALIZABLE_READ就不需要设置其他的了,即解决了幻读问题那么脏度和不可重复读自然就都解决了。

请你简单介绍一下,数据库水平切分与垂直切分

垂直拆分就是要把表按模块划分到不同数据库表中,单表大数据量依然存在性能瓶颈

水平切分就是要把一个表按照某种规则把数据划分到不同表或数据库里。

● 请你讲讲 Statement 和 Prepared Statement 的区别?哪个性能更好?

与Statement相比,①PreparedStatement接口代表预编译的语句,它主要的优势在于可以减少SQL的编译错误并增加SQL的安全性(减少SQL注射攻击的可能性);②PreparedStatement中的SQL语句是可以带参数的,避免了用字符串连接拼接SQL语句的麻烦和不安全;③当批量处理SQL或频繁执行相同的查询时,PreparedStatement有明显的性能上的优势,由于数据库可以将编译优化后的SQL语句缓存起来,下次执行相同结构的语句时就会很快

mysql数据库的索引类型

索引数据结构:二叉树、红黑树、hash表、B-tree

1、普通索引当一张表,把某个列设为主键的时候,则该列就是主键索引

2、唯一索引索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

3、主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。

5、全文索引主要用来查找文本中的关键字,而不是直接与索引中的值相比较。

InnoDB索引实现(聚集)?

数据文件本身就是索引文件
表数据文件本身就是按B+树组织的一个索引结构文件
聚集索引的叶子节点包含了完整的数据记录
表必须有主键,且推荐使用整型的自增主键
普通索引结构叶子节点存储的是主键值
InnoDB主键索引查找流程:通过.ibd文件找到对应的索引,索引的value即为那行对应的完整数据

聚集索引和非聚集索引的区别?

聚集索引:表中那行数据的索引和数据都合并在一起了。

非聚集索引:表中那行数据的索引和数据是分开存储的。

作者:希望秋招拿到offer
链接:https://www.nowcoder.com/discuss/452732
来源:牛客网

一个 SQL 执行的很慢,我们要分两种情况讨论:

1、偶尔很慢,则有如下原因

(1)、数据库在刷新脏页,例如 redo log 写满了需要同步到磁盘。

(2)、执行的时候,遇到锁,如表锁、行锁。

2、这条 SQL 语句一直执行的很慢,则有如下原因。

(1)、没有用上索引:例如该字段没有索引;由于对字段进行运算、函数操作导致无法用索引。

(2)、数据库选错了索引。

缓存穿透:

恶意请求缓存中不存在的数据,所有求情都落到数据库造成短时间内承受大量请求而崩掉

(一)利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试

(二)采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。

(三)提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。

请说明一下锁机制的作用是什么?并且简述一下Hibernate的悲观锁和乐观锁机制是什么?

有些业务逻辑在执行过程中要求对数据进行排他性的访问,于是需要通过一些机制保证在此过程中数据被锁住不会被外界修改,这就是所谓的锁机制。
Hibernate支持悲观锁和乐观锁两种锁机制。悲观锁,顾名思义悲观的认为在数据处理过程中极有可能存在修改数据的并发事务(包括本系统的其他事务或来自外部系统的事务),于是将处理的数据设置为锁定状态。悲观锁必须依赖数据库本身的锁机制才能真正保证数据访问的排他性,乐观锁,顾名思义,对并发事务持乐观态度(认为对数据的并发操作不会经常性的发生),通过更加宽松的锁机制来解决由于悲观锁排他性的数据访问对系统性能造成的严重影响。

HashMap的底层实现

底层由链表+数组实现
可以存储null键和null值
线性不安全
初始容量为16,扩容每次都是2的n次幂(保证位运算)
加载因子为0.75,当Map中元素总数超过Entry数组的0.75,触发扩容操作.
并发情况下,HashMap进行put操作会引起死循环,导致CPU利用率接近100%
HashMap底层是数组和链表的结合。HashMap通过key的HashCode经过扰动函数处理过后得到Hash
值,然后通过位运算判断当前元素存放的位置,如果当前位置存在元素的话,就判断该元素与要存入的元素的hash值以及key是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。当Map中的元素总数超过Entry数组的0.75时,触发扩容操作,为了减少链表长度,元素分配更均匀。

哈希冲突:如果两个不同对象的hashCode相同,这种现象称为hash冲突。

有以下的方式可以解决哈希冲突:

开放定址法
再哈希法
链地址法
建立公共溢出区

请你说明HashMap和Hashtable的区别?

HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
HashMap允许键和值是null,而Hashtable不允许键或者值是null。
Hashtable是同步的,而HashMap不是。HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。

HashMap和TreeMap的区别
HashMap:数组方式存储key/value,线程非安全,允许null作为key和value,key不可以重复,value
允许重复,不保证元素迭代顺序是按照插入时的顺序,key的hash值是先计算key的hashcode值,然后
再进行计算,每次扩容会重新计算key的hash值,会消耗资源,要求key必须重写equals和hashcode方
法。它默认初始容量为16,加载因子0.75,扩容为旧容量的2倍,查找元素快,如果key一样则比较value,
如果value不一样,则按照链表结构存储value,就是一个key后面有多个value
TreeMap:基于红黑树的NavigableMap实现,线程非安全,不允许null,key不可以重复,value允许重
复,存入TreeMap的元素应当实现Comparable接口或者实现Comparator接口,会按照排序后的顺序
迭代元素,两个相比较key不得抛出classCastException。主要用于存入元素的时候对元素进行自动排
序,迭代输出的时候就按照排序顺序输出。

请你说明一下TreeMap的底层实现?

TreeMap 的实现就是红黑树数据结构,一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点。

红黑树的插入、删除、遍历时间复杂度都为O(lgN),所以性能上低于哈希表。但是哈希表无法提供键值对的有序输出,红黑树因为是排序插入的,可以按照键的值的大小有序输出。

红黑树的性质:

1.节点是红色或黑色。

2.根节点是黑色。

3.每个叶子节点都是黑色的空节点(NIL节点)。

4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

平衡二叉树的性质:

它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。这个方案很好的解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(logN)。但是频繁旋转会使插入和删除牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了很多。

1、红黑树放弃了追求完全平衡,追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单。

2、平衡二叉树追求绝对平衡,条件苛刻,实现起来比较麻烦,每次插入新节点之后需要旋转的次数不能预知。

请问什么是死锁(deadlock)?

两个线程或两个以上线程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是这些线程都陷入了无限的等待中。如何避免线程死锁?
只要破坏产生死锁的四个条件中的其中一个就可以了。
破坏互斥条件:这个条件我们没有办法破坏,因为我们用锁本来就是想让他们互斥的(临界资源需要互斥访问)。
破坏请求与保持条件:一次性申请所有的资源。
破坏不剥夺条件:占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。
破坏循环等待条件:靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放

synchronized关键字和volatile关键字比较:

volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。
多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞
volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。
volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值