本文主要是介绍顺网面经,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
object中equal重写一般什么时候用到?在equal重写时需要注意什么?
一。 在重写equals方法时,要注意满足离散数学上的特性
1 自反性:对任意引用值X,x.equals(x)的返回值一定为true.
2 对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
3 传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true
4 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变
5 非空性:任何非空的引用值X,x.equals(null)的返回值一定为false
二。 在重写equals方法时,还要顺手把 hashCode方法一起重写了。
这一点主要是考虑和集合类协同工作的需要。一般集合为加快存取速度,通常使用类hashtable的方式存取对象,
hashCode() && equals() 则是判断待查找元素与集合中某个元素相等的依据。 而java中默认的hashCode是
由对象的内存地址生成的, 如果重写了equals 而 重写 hashCode, 则会造成“A和B相等,A加入集合后,用B查询集合却查不到”的悖论。
https://www.cnblogs.com/silence-hust/p/4558701.html
String的源码有看过吗?为什么是不可变的?在字节码中是如何的?
1、private final成员变量
2、Public 的方法都是复制一份数据
String 有很多 public 方法,每个方法都将创建新的 String 对象,比如 substring 方法
3、String 是 final 的
String 被 final 修饰,因此我们不可以继承 String,因此就不能通过继承来重写一些方法。
4、构造函数深拷贝
当传入可变数组 value[] 时,进行 copy 而不是直接将 value[] 复制给内部变量,直接复制其实是复制的引用。所以我们认为其是不可变对象。但是真的不可变吗?
每个字符串都是由许多单个字符组成的,我们知道其源码是由 char[] value 字符数组构成。
value 被 final 修饰,只能保证引用不被改变,但是 value 所指向的堆中的数组,才是真实的数据,只要能够操作堆中的数组,依旧能改变数据。而且 value 是基本类型构成,那么一定是可变的,即使被声明为 private,我们也可以通过反射来改变。
字节码:https://blog.csdn.net/weixin_34279579/article/details/92524735
项目中有用到反射吗?是怎么用的?
switch现在支持字符串判断,为什么不允许switch null?
如果您使用带引用类型的开关(例如盒装基元类型),如果表达式为null,则会发生运行时错误,因为取消装箱会抛出NPE。
所以无论如何都无法执行null(这是非法的)
synchronized是如何实现锁的?在字节码中是怎么表现的?锁升级过程是怎么样的?
CAS是怎么实现的?java中是怎么使用的(需要几个传参)?
JVM中内存模型了解吗?
为什么要在方法中使用栈这个结构(虚拟机栈为什么是栈)?(个人理解问题可以演变为:为什么要分堆和栈)
(1)从软件设计的角度来看,栈代表了处理逻辑,而堆代表了数据,这样分离使得处理逻辑更为清晰。这种隔离、模块化的思想在软件设计的方方面面都有体现。
(2)堆与栈的分离,使得堆中的内容可以被多个栈共享。这种共享有很多好处,一方面提供了一种有效的数据交互方式(如内存共享),另一方面,节省了内存空间。
(3)栈因为运行时的需要(如保存系统运行的上下文),需要进行址段的划分。由于栈只能向上增长,因此会限制住栈存储内容的能力。而堆不同,堆的大小可以根据需要动态增长。因此,堆与栈的分离,使得动态增长成为可能,相应栈中只需要记录堆中的一个地址即可。
(4)堆和栈的完美结合就是面向对象的一个实例。其实,面向对象的程序与以前结构化的程序在执行上没有任何区别,但是面向对象的引入使得对待问题的思考方式发生了改变,是更接近于自然的思考方式。当把对象拆开会发现,对象的属性其实就是数据,存放在堆中,而对象的方法就是处理逻辑,存放在栈中。我们编写对象的时候,其实即编写了数据结构,也编写了处理数据的逻辑。
总结:栈主要用来执行程序,堆主要用来存放对象,为栈提供数据存储服务。也正是因为堆与栈分离的思想才使得JVM的垃圾回收成为可能。
内存逃逸和栈内分配了解吗?
spring的源码有看过吗?如何解决循环依赖的?
https://blog.csdn.net/sinat_32023305/article/details/109720581
beanFactory和FactoryBean有什么区别?
BeanFactory 以Factory结尾,表示它是一个工厂类,用于管理Bean的一个工厂
在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。
但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,
一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,
如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。
spring中AOP什么时候会失效?
(1)在Spring AOP 代理时, 拦截器在目标方法执行前后进行拦截,
DynamicAdvisedInterceptor
(CglibAopProxy 的内部类)的 intercept 方法或JdkDynamicAopProxy
的 invoke 方法会间接调用AbstractFallbackTransactionAttributeSource
的computeTransactionAttribute
方法,获取注解的配置信息。此方法会检查目标方法的修饰符是否为 public,不是 public则不会获取注解的属性配置信息。所以:
protected
、private
修饰的方法上使用@Transactional
注解,虽然事务无效,但不会有任何报错(2)只有当方法被当前类以外的代码调用时,才会由
Spring
生成的代理对象来管理
springboot中自动装配了解吗?如何自己写一个starter?
sql优化有做过吗?怎么做的?
什么时候索引会失效?
like通配符可能会导致索引失效
or左右两边的查询列是否命中相同的索引
在索引列上使用内置函数,一定会导致索引失效
隐式类型转换导致的索引失效(bigint用varchar查)
隐式字符编码转换导致的索引失效(utf8mb4用utf-8)
对索引列进行运算,一定会导致索引失效(使用+,-,*,/)
联合索引中,where中索引列违背最左匹配原则,一定会导致索引失效
回表成本过大,不如直接全表扫描
mysql5.6以上版本的CRR(CMR?忘记说的是什么了)有听过吗?
mysql的Hash索引和全文索引了解吗?
mysql中的锁了解吗?什么时候会加锁?并发条件下如何使用mysql锁实现业务中的上锁?
对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X)
mysql InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select ...for update语句,加共享锁可以使用select ... lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select ...from...查询数据,因为普通查询没有任何锁机制
单个update不加事务注解会加锁吗?
MySQL采用autocommit模式运行。
使用
create
、alter
、delete
语句去修改数据库、表、视图、存储过程等数据库对象的时候,就会隐式提交当前事务
mysql在各个事务隔离级别中锁的表现又是如何
1、Read uncommitted
Mysql设置Read uncommitted隔离级别,数据库在修改(update)数据时,使用的是共享锁,所以在修改数据未提交事务时,查询(select)语句是能查到此时修改的数据,如果回滚了修改的数据,则查询到的数据是有问题的,造成了脏读。该隔离级别下查询不加锁,主要涉及到的是共享锁
2、Read committed
数据库在修改(update)数据时,使用的是排他锁,查不加锁
3、Repeatable readMysql默认的隔离级别,读操作利用多版本并发控制(
MVCC
),写操作进行加排他锁
4、Serializable直接对操作的表加表锁,其他事务不能读写该表,效率比较低
mysql的死锁检测是怎么做的?
当死锁出现时,Innodb会主动探知到死锁,并回滚了某一苦苦等待的事务。问题来了,Innodb是怎么探知死锁的?
核心就是数据库会把事务单元锁维持的锁和它所等待的锁都记录下来,Innodb提供了wait-for graph算法来主动进行死锁检测,每当加锁请求无法立即满足需要进入等待时,wait-for graph算法都会被触发。当数据库检测到两个事务不同方向地给同一个资源加锁(产生循序),它就认为发生了死锁,触发wait-for graph算法。比如,事务1给A加锁,事务2给B加锁,同时事务1给B加锁(等待),事务2给A加锁就发生了死锁。那么死锁解决办法就是终止一边事务的执行即可,这种效率一般来说是最高的,也是主流数据库采用的办法。
Innodb目前处理死锁的方法就是将持有最少行级排他锁的事务进行回滚。这也是相对比较简单的死锁回滚方式。死锁发生以后,只有部分或者完全回滚其中一个事务,才能打破死锁。对于事务型的系统,这是无法避免的,所以应用程序在设计必须考虑如何处理死锁。大多数情况下只需要重新执行因死锁回滚的事务即可。
死锁超时也是一种常见的做法,就是等待锁持有时间,如果说一个事务持有锁超过设置时间的话,就直接抛出一个错误,参数innodb_lock_wait_timeout用来设置超时时间。如果有些用户使用哪种超长的事务,你就需要把锁超时时间大于事务执行时间。在这种情况下这种死锁超时的方式就会导致每一个死锁超时被发现的时间是无法接受的。
Synchronized关键字加在普通方法上和加在静态方法上有什么区别?
synchronized修饰不加static的方法,锁是加在单个对象上,不同的对象没有竞争关系;
synchronized修饰加了static的方法,锁是加载类上,这个类所有的对象竞争一把锁。
Synchronized加在方法上和加在方法内部的区别?
同步方法锁的范围比较大,而同步代码块范围要小点,一般同步的范围越大,性能就越差,一般需要加锁进行同步的时候,肯定是范围越小越好,这样性能更好
spring如何处理线程并发问题?
在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。
ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
一个请求怎么从Tomcat到Spring的流程?
https://www.cnblogs.com/Soy-technology/p/11241795.html
Http请求头里都放了些什么东西?
https://blog.csdn.net/melody_day/article/details/53559054
TCP是如何保证可靠投递的?
Https加密协议SSL具体怎么加密的?
这篇关于顺网面经的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!