码迷,mamicode.com
首页 > 编程语言 > 详细

java 面试整理【持续整理中】

时间:2019-02-19 11:43:13      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:fas   防止   应该   这一   htm   ringbuf   监视器   表单   同步   

String、StringBuffer与StringBuilder之间区别
  String:在java中字符串属于java对象,java提供了string类来创建和操作字符串。但是值得注意的是string属于字符串常量,值是不会变的。
    这就导致了每次对string的操作都会生成新的string对象。这样不仅效率低下,还比较浪费内存空间。所以为了解决这一问题,就有了stringBuffer和stringBuilder;
  StringBuffer:字符串变量 线程安全的。可以多次操作不会产生新的未使用对象
  stringBuilder:字符串变量 非线程安全的。可以多次操作不会产生新的未使用对象
  但是在速度方面,stringBuilder > stringBuffer > String
  所以多数情况下使用stringBuilder,但是如果是程序要求线程安全的情况下就必须使用StringBuffer
  总结:
    如果要操作少量数据则使用String
    多线程字符串缓冲区下操作大量数据用StringBuffer
    单线程字符串缓冲区下操作大量数据用StringBuilder

fail-fast vs fail-save
  同步修改/并发修改:当一个或多个线程正在遍历一个集合collection,此时另一个线程修改了集合的内容(增加、删除或修改),这就是并发修改/同步修改

  fail-fast机制:当一个线程在遍历一个集合时,当集合结构被修改,会抛出concurrent modification exception
  fail-fast在两种情况下抛出concurrent modification exception
    1、单线程下,在遍历它的过程修改了结构,注意:remove()方法会让expectModcount 和modcount相等,所以不会抛异常。
    2、多线程下,当一个线程在遍历集合,而另一个线程对该集合结构进行了修改。
  fail-safe机制:对任何集合的修改都会在复制的集合上进行修改,因此不会抛出concurrent modification excption
  fail-safe机制有两个问题;
    1、需要复制集合,产生大量无效对象,开销大
    2、无法保证读取到的数据是否为目前原数据结构中的数据

happens-before:
  如果两个操作之间存在happens-before关系,那么前一个操作的结果就会对后面一个操作可见。(如果一个操作的结果对另一个操作可见,那么他们之间存在happens-before.)
  happens-before规则:
    1、程序次序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
    2、监视器锁规则:对一个监视器锁的解锁,happens-before于随后对这个监视器锁的加锁。
    3、volatile变量规则:对于一个volatile域的写,happens-before于任意后续对这个volatile域的读。
    4、传递性:如果A happens-before B,B happens-before C ,那么 A happens-before C。
    5、start规则:如果线程A 执行操作ThreadB.start()【启动线程B】,那么A 线程的ThreadB.start()操作happens-before于线程B的任意操作
    6、join规则:如果线程A 执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于ThreadB.join操作成功返回。

volatile vs synchronized
  java多线程有三大特性:原子性、可见性、有序性
      原子性:是指线程的多个操作是一个整体,不能被分割。要么就不执行,要么就全部执行,中间不能被打断。
      可见性:是指线程之间的可见性。就是一个线程修改后,其他线程立马能够知道。
      有序性:为了提高执行效率,java的编译器和处理器可以对指令进行重新排序,重新排序会影响多线程并发的正确性,有序性就是保证不进行重新排序。
    volatile关键字的作用就是保证可见性和有序性,但不保证原子性。如果一个共享变量被volatile修饰,那么当有一个线程修改了这个共享变量后,其他线程也立马进行修改;
  volatile同时能禁止指令重新排序,在指令重排序优化时,在volatile变量之前的指令不能在volatile之后执行,反之同理。
  synchronized关键字提供了同步锁的概念,被synchronized修饰的代码可以防止被多个线程同时执行,因为synchronized保证了在同一时刻只能有一个线程执行同步代码块,
    所以执行同步代码块的操作相当于单线程。那么线程的三大特性都能保证了。
  volatile和synchronized的区别:
    1、volatile只能用在变量,范围较小。而synchronized则可以用在变量、方法。类、同步代码块等,范围较大。
    2、volatile只能保证可见性与有序性,不能保证原子性。而synchronized三大特性都可以。
    3、volatile不会造成线程阻塞,而synchronized会造成线程阻塞。

request.getParameter()、request.getInputStream()、request.getReader():

  request.getParameter()、request.getInputStream()、request.getReader()这三个方法都是从request对象得到提交的数据,但各有不同;

  request.getParameter():form的一个关键属性enctype=application/x- www-form-urlencoded,这也是默认的编码方式。编码后的结果通常是
    field1=value1&field2=value2...等。
    例:name=aaa&pwd=bbb;
    这应该属于最常用的获取提交数据,但弊端是对于传输较大块的二进制数据显得力不从心。

  request.getInputStream()、request.getReader(): form的编码方式为: "multipart/form-data"
    浏览器可以很容易将表单内的数据和文件放在一起发送。这种编码方式先定义好一个不可能在数据中出现的字符串作为 分界符,然后用它将各
    个数据段分开,而对于每个数据段都对应着 HTML 页面表单中的一个 Input 区,包括一个 content-disposition 属性,说明了这个数据段的一些
    信息,如果这个数据段的内容是一个文件,还会有 Content-Type 属性,然后就是数据本身,如果以这种方式提交数据就要用
    request.getInputStream()或request.getReader()得到 提交的数据,用 request.getParameter()是得不到提交的数据的。

  值得注意的是:request.getParameter()、request.getInputStream()、request.getReader()三个方法是有冲突的,因为流只能被读一次。

java 面试整理【持续整理中】

标签:fas   防止   应该   这一   htm   ringbuf   监视器   表单   同步   

原文地址:https://www.cnblogs.com/su-zhifei/p/10399884.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!