1. int转long
long val = 24 * 60 * 60 * 1000 * 1000l;
long val1 = 24 * 60 * 60 * 1000 * 1000;
System.out.println(Integer.MAX_VALUE);
System.out.println(Long.MAX_VALUE);
System.out.println(Long.MIN_VALUE);
System.out.println(24 * 60 * 60 * 1000);
System.out.println(val);
System.out.println(val1);
System.out.println(val / 60 / 60 / 1000 / 1000);
// 1 这里最后结果是0的原因是计算过程中产生的是int再转的long
System.out.println(val1 / 60 / 60 / 1000 / 1000);
2. 引用传递
另外:对于打印char[] :
char类型的数组就相当于一个字符串。
char类型的数组就相当于一个字符串。
因为输出流System.out是PrintStream对象,PrintStream有多个重载的println方法,其中一个就是public void println(char[] x),直接打印字符数组的话,不像int[]等其他数组,它会直接调用这个方法来打印,因而可以打印出数组内容,而不是地址。
3. ConcurrentHashMap的put方法简述
自己的答案:
- 先判断当前容器是否被初始化,如果没有初始化则先初始化
- 然后先根据key使用(key & (len - 1))的方式计算出所在位置
- 如果该位置为空,则直接使用CAS插入即可,然后判断此时是否达到了阈值,是则进行扩容。
- 如果该位置不为空,则需要先加锁
- 然后先通过hash进行比较,相等再通过equals比较是否相等,相等则直接替换值,如果不相等再看该节点是链表节点还是红黑树节点,然后按照对应数据结构的遍历方式依次遍历,直到相等后替换值或者找不到则插入对应的数据结构,插入之前如果是链表则需要考虑是否满足条件(元素size大于64,链表长度大于8),是则转换为红黑树。
- 看是否达到了阈值,达到了就扩容
根据源码补充的答案:
1. 先对key使用扰动方法((key.hashCode() ^ (key.hashCode() >>> 16)) & 0x7fffffff)得到hash值
2. 判断是否为null,是则进行初始化(初始化过程中只能让一个线程初始化)
3. 然后根据hash值通过hash & (len - 1)得到所在位置
4. 判断所在位置是否为空,为空直接使用CAS插入
5. 如果不为空,则先加锁(Synchronzied),加锁范围限制在通过hash找到的节点上
6. 先判断f节点是链表节点还是红黑树节点,是链表节点的话,通过for循环一个节点一个节点的判断(先判断hash,再判断是否相等),最后找到了节点的话,就替换值,如果没有找到,则在尾部插入
7. 是红黑树的话,则依照红黑树的遍历方式遍历最后插入或替换
8. 此时同步块结束,开始判断如果是链表,看是否满足条件(转化为红黑树的条件),满足则转换。
9. 此时增加size,看是否达到阈值,达到则扩容
4. 有三个bean A、B、C;其中,A依赖于B,B依赖于C,C又依赖于A,这样能否正常启动?
Spring中循环依赖场景有:
(1)构造器的循环依赖
(2)field属性的循环依赖
其中,构造器的循环依赖问题无法解决,只能拋出BeanCurrentlyInCreationException异常,在解决属性循环依赖时,spring采用的是提前暴露对象的方法。
https://blog.csdn.net/xx897115293/article/details/108635440
https://www.cnblogs.com/jajian/p/10241932.html
https://zhuanlan.zhihu.com/p/62382615
https://segmentfault.com/a/1190000019286083
5. spring bean 如何保持线程安全,为什么?
对于有状态的bean(比如Model和View),就需要自行保证线程安全,最浅显的解决办法就是将有状态的bean的作用域由“singleton”改为“prototype”。
也可以采用ThreadLocal解决线程安全问题,为每个线程提供一个独立的变量副本,不同线程只操作自己线程的副本变量。
https://www.cnblogs.com/frankcui/p/14341795.html
6. 现有集合ArrayList list = new ArrayList(); 利用反射机制在这个泛型为Integer的ArrayList中存放一个String类型的对象。
先解释:
可以使用反射技术,来获得add方法,这样的话就可以随便存了,sun规定的泛型只是将错误上升到编译时期,在运行时期没有泛型的。直接使用反射得到add方法就不会再有泛型的限制了
代码:
public static void main(String[] args) throws Exception {
List<Integer> list = new ArrayList<Integer>(); //定义Integer泛型
String str = "abc";
Method[] method=list.getClass().getMethods();//取得list的所有方法
System.out.println(method.length);
for(int i=0;i<method.length;i++){
System.out.println(method[i]);//遍历打印list的方法
}
//通过反射来执行list的第一个方法,第一个是list对象,代表该对象的方法,第二个是方法参数
method[0].invoke(list, str);
System.out.println(list.size());