当前位置: 首页 > wzjs >正文

手机能看的网站深圳网络推广外包

手机能看的网站,深圳网络推广外包,wordpress站6个月300mb,b2c商城定制前言 最近准备换工作了,八股文重新复习一边,又有了新的感悟,对于以前不清晰的点,这一次也彻底搞清楚,绝不给面试官留机会。 new String(“abc”)会创建几个对象? 回答 如果字符串常量池中存在abc字面量引用…

前言

最近准备换工作了,八股文重新复习一边,又有了新的感悟,对于以前不清晰的点,这一次也彻底搞清楚,绝不给面试官留机会。

new String(“abc”)会创建几个对象?

回答

如果字符串常量池中存在abc字面量引用,则只是创建一个对象。如果不存在,就会在创建String对象时,再创建abc字面量对象 并将引用放到常量池中。所以,如果是第二种情况,就会创建两个对象。

扩展

那么,问题来了,第二次 new String(“abc”),他会创建几个对象呢?答案是 三个对象。因为第一次new String(“abc”)的时候,他已经把abc放到常量池中了。所以第二次,只需要创建一个String对象,然后去常量池中拿到abc字面量的引用即可。

再扩展

为什么字符串常量池不能存字面量具体值,而是需要在堆中创建,他自己引用呢。
实际上,在jdk6及之前,字符串常量池是在方法区中的永久代里面的,jdk7及以后,才挪到堆中的。而在方法区中的时候,他确实存的是字面量的值。但是后来发现,这样存,一旦字面量过多,方法区就会被撑大,最后内存溢出GG了。所以,后面挪到堆中,不使用了,没有引用关系了,对象就借助垃圾回收器进行回收,避免OOM。

你知道一个java对象的创建过程是怎么样的吗?

回答

类加载 --> 内存分配 --> 初始化 -->设置对象头  --> 调用init方法

在这里插入图片描述
1,JVM在遇到new指令时,类加载器会进行检查类是否被加载。如果被加载,则下一步。没有被加载,则进行类的加载,步骤为,加载,验证,解析,初始化。
2,完成初始化后,就进入了内存分配阶段,由于已经初始化完成,所以此时就已经知道了加载对象的大小。基于对象的大小,去分配内存空间,分配的方式有两种,指针碰撞和空闲列表。JVM基于内存空间是否规则,决定使用哪种方式。内存规则,则使用指针碰撞,不规则,则使用空闲列表,维护一个列表用于记录可用的内存块。
3,初始化零值,为所有默认成员变量赋默认值。int 为0,String 为null,boolean默认为false,保证对象在不显示初始化时,也能使用。
4,设置对象头,Mark Word 存放哈希码,GC分代年龄以及锁状态。Klass Pointer 指向类元数据的指针(JVM通过这个指针判断当前对象所属哪个类) 数组长度(数组对象)

在完成上面这些的时候,对于JVM来说,就已经完成了对象的创建。

5,对于Java来说,此时还需要调用对象的init方法,按照代码逻辑 初始化成员变量。如果有父类对象,则先调用父类的构造方法,完成父类的初始化。
6,将堆中的对象地址 赋给栈中引用变量,此时对象才能真正可用。

扩展

类加载触发时机 除了JVM碰到new字段之外 在遇到静态字段或者方法 以及反射调用(Class.forName())也会触发。

public class Person {private int age = 10;public Person(){this.age = 11;}public int getAge() {return age;}
}
public static void main(String[] args) {Person p= new Person();System.out.println(p.getAge());}

当我们 new Person的时候 就会触发JVM的类加载机制,进行检查,存在则分配内存,不存在则进行加载。内存分配完成后,就会初始化age为0,紧接着 设置对象头,调用构造方法 给age赋值,如果这里不赋值,就会使用默认值,最后 将堆中的内存地址 交给栈的p,让他可以调用。

什么时受检异常,非受检异常?

回答

所谓的受检异常,其实就是在我们编码过程中,需要手动捕捉或者抛出的异常,
非受检异常,则是在编译阶段不会显示报出,只有在运行时出错了,才会报出来 的异常。

扩展

手写一个受检异常和非受检异常给大家看看。
受检异常,注意,下面的main方法中 需要捕捉 或者throws抛出 否则编译就会不通过。

public class CheckedException extends Exception{public CheckedException(String message)  {super(message);}public CheckedException(String message, Throwable cause) {super(message, cause);}}public static void main(String[] args) throws Exception {div(1d,0d);}private static double div(double a, double b) throws Exception {if (b == 0) {throw new CheckedException("除数不能为0");}return a / b;}

非受检异常,就是继承Exception的子类RunTimeException,在运行时出错 才会报出来的异常。注意,这里我没有捕捉 或者抛出异常 也可以编译通过,只是在运行时 会抛出错误。

public class CheckedException extends RuntimeException{public CheckedException(String message)  {super(message);}public CheckedException(String message, Throwable cause) {super(message, cause);}}public static void main(String[] args) {div(1d,0d);}private static double div(double a, double b) {if (b == 0) {throw new CheckedException("除数不能为0");}return a / b;}

fail-safe,fail-fast是什么?

回答

fail-fast 快速失败,fail-safe 安全失败。
这两种都是为了处理并发操作集合产生的安全性问题。

fail-fast 针对的是 单线程环境下 对集合进行遍历时 向集合中存放或者删除数据,此时就会抛出一个ConcurrentModifictionException错误,代表着遍历失败。常用的集合代表,ArrayList,HashMap,HashSet.

fail-safe 则是多线程环境下,对集合的修改,不会抛出错误 但是迭代的接口不保证包含新修改或者增加的数据。这个本质是就是迭代器操作的时集合的副本 或者某一时刻的快照,而修改的时原集合 因为他是弱一致性的 所以时效性无法保证。 常用的集合代表,ConcurrentHashMap,CopyOnWriteArrayList。

扩展

写一个fail-fast给大家看看。此时,迭代里面想要给集合新增加一个数据,就会抛出ConcurrentModificationException错误,迭代遍历失败。

 public static void main(String[] args) {Map<String, Object> map = new HashMap<>();map.put("1", "1");map.put("2", "2");Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();while (iterator.hasNext()){Map.Entry<String, Object> next = iterator.next();System.out.println(next.getKey() + " " + next.getValue());map.put("3", "3");}}

再写一个fail-safe,此时不会报错,而且 新加入的数据也能打印出来,看起来似乎没有达到我们想要效果。迭代器中存的时集合的副本,那为什么新加入到集合中的数据 也能打印出来呢?

   public static void testConcurrentHashMap() {String s = new String("a");ConcurrentHashMap<String, Object> concurrentHashMap = new ConcurrentHashMap<>();//存储一些测试值concurrentHashMap.put("1", "1");concurrentHashMap.put("2", "2");Iterator<Map.Entry<String, Object>> iterator = concurrentHashMap.entrySet().iterator();while (iterator.hasNext()) {Map.Entry<String, Object> next = iterator.next();System.out.println(next.getKey() + " " + next.getValue());concurrentHashMap.put("4", "4");}}

这是因为,集合的本质 其实就是数据+链表+红黑树,我们知道 数组默认时16,达到它0.75也就是14的时候 他就会扩容,在此之前 他不扩容,且采用的是节点上的分段锁来进行管理的。也就是说 我们给他12个数据 再迭代时 新增数据 他就无法操作到了。

  public static void testConcurrentHashMap() {String s = new String("a");ConcurrentHashMap<String, Object> concurrentHashMap = new ConcurrentHashMap<>();//存储一些测试值for (int i = 0; i < 12; i++) {concurrentHashMap.put(String.valueOf(i), i);}Iterator<Map.Entry<String, Object>> iterator = concurrentHashMap.entrySet().iterator();while (iterator.hasNext()) {Map.Entry<String, Object> next = iterator.next();System.out.println(next.getKey() + " " + next.getValue());concurrentHashMap.put("17", "17");}System.out.println("==============================================================");Iterator<Map.Entry<String, Object>> iterator1 = concurrentHashMap.entrySet().iterator();while (iterator1.hasNext()) {Map.Entry<String, Object> next = iterator1.next();System.out.println(next.getKey() + " " + next.getValue());}}

HashMap如何解决哈希冲突?

回答

首先 我们需要知道,HashMap的key 时通过哈希算法将输入任意长度的值,转化为输出一个固定长度的值,我们输入的东西时无限的,但是输出是有限的,所以 就会产生重复的key值。
为了解决这个问题,HashMap采用的是链式寻址法,以单项链表的方式,在数组的节点下面挂上链表,进行存储。如果超过8位,且数据长度超过64则转变为红黑树,增加查询效率。

扩展

那除了 链式寻址法之外 还有其他方法可以解决哈希冲突吗?

当然是有的。

就比如,ThreaLocal使用的开发定址法,也称之为 线性探测法,从冲突的位置,按照一定的次序,找到一个合适的位置,进行存储。

还有 再哈希,就是重复的key,再进行哈希运算,直到得出一个不重复的key,但这样做 就比较耗费性能,毕竟,本来应该一次算出来的东西,多次通过散列表运算。

还可以 建立公共区 和溢出区 公共区存放正常的数据,溢出区则存储冲突的数据。

JDK动态代理,为什么只能代理有接口的类?

回答

JDK动态代理 是通过反射和接口实现的,代理类需要继承Proxy类,我们知道,Java是单继承的,所以,继承了Proxy后,就无法再继承其他类类,只能实现接口。

JDK动态代理的初衷,是面向接口编程,推荐使用接口解耦合。如果想要代理类,可以使用CGLIB来进行代理。Spring AOP就是采用JDK动态代理。

扩展

写一个JDK动态代理的例子 给大家看看。在Proxy.newProxyInstance代理接口的时候 运行时 就会生成一个Proxy0继承Proxy然后实现这个接口。

public interface UserService {void addUser(String name);void deleteUser(String id);
}
public class UserServiceImpl implements UserService{@Overridepublic void addUser(String name) {System.out.println("add user: " + name);}@Overridepublic void deleteUser(String id) {System.out.println("delete user: " + id);}
}
public class UserProxy {public static UserService createUserProxy(UserService userService) {return (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{UserService.class}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("before");Object result = method.invoke(userService, args);System.out.println("after");return result;}});}}public static void main(String[] args) {UserServiceImpl userService = new UserServiceImpl();UserService userServiceProxy = UserProxy.createUserProxy(userService);userServiceProxy.addUser("tongz");}

再看看CGLIB动态代理。

public class CglibProxyFactory {public static UserService createUserServiceProxy() {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(UserServiceImpl.class);enhancer.setCallback(new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("before");System.out.println("method:" + method.getName());Object result = methodProxy.invokeSuper(o, objects);System.out.println("after");return result;}});return (UserService) enhancer.create();}
}public static void main(String[] args) {UserService userServiceProxy = CglibProxyFactory.createUserServiceProxy();userServiceProxy.addUser("tongz");}

String StringBuffer StringBuilder

回答

不可变性 String 它的value是final修饰的,不可变。每次修改String的值 都会产生一个新的对象。StringBuilder 和 StringBuffer是可变更的 不会产生新的类。

线程安全性来说 String 不可变 是线程安全的。StringBuffer也是线程安全的,每个操作方法
都有一个synchronized关键字修饰。StringBuilder不安全。

性能上 StringBuilder最好 其次 StringBuffer 再次 String,因为String每次修改都要创建新的对象,而StringBuffer则不需要创建对象 但是他加了同步锁,影响性能。

内存上 String 引用存储在字符串常量池 StringBuffer和StringBuilder存储在堆内存空间。

扩展

没啥好扩展的,看一下StringBuffer的源码吧。方法上都有synchronized修饰。
在这里插入图片描述

http://www.dtcms.com/wzjs/144047.html

相关文章:

  • 自己怎么用h5做网站百度app客服人工在线咨询
  • 网站建设公司有哪些seo关键词排名优化怎么收费
  • 网站建设与管理课件信息流广告投放平台
  • 公司网站招聘费如何做会计分录电商平台app大全
  • 需要建设网站的哪个搜索引擎能搜敏感内容
  • 云南做网站新闻头条最新
  • 门户网站系统开发在线crm软件
  • 网站建设绿茶科技可以直接进入的舆情网站
  • 重庆建网站方法网络优化公司排名
  • 移动网站开发 王府井广州网站制作公司
  • 水务 网站建设刷外链网站
  • 深圳公司网站设计b2b电子商务平台
  • 携程特牌 的同时做别的网站种子搜索神器下载
  • b2c购物网站建设方案官网seo哪家公司好
  • 浦西网站建设沙坪坝区优化关键词软件
  • 株洲网站平台搭建网址提交百度收录
  • 网站开发面板网上教育培训机构哪家好
  • 淄博网站制作sem 推广软件
  • 建站教程的特点线上营销平台有哪些
  • wordpress网页怎么上传保定百度seo公司
  • 要屏蔽一个网站要怎么做计算机培训机构
  • 做网站用什么语营销网站seo推广
  • 中小型网站设计公司百度首页百度一下
  • 投教网站建设免费seo关键词优化排名
  • 扶贫工作网站建设方案百度关键词搜索排名
  • 济南网站建设靠谱公司北京百度推广电话号码
  • 百度小程序官网重庆的seo服务公司
  • 常州市钟楼区建设局网站温州seo外包公司
  • 男女直接做性视频网站引擎搜索
  • 最新新闻头条国家大事国际新闻seo教程seo入门讲解