牛客网java刷题个人错题总结复习(持续更新)




这个是个人的错题复习总结,不对的地方也请大家多多评论,谢谢。


java中构造器、初始化块、静态初始化块的执行顺序。

1.静态初始化块>初始化块>构造器

2.父类>子类

综合顺序:父类静态初始化块

                  子类静态初始化块

                  父类初始化块

                  父类构造器

                  子类初始化块

                  子类构造器

ps:静态初始化块是在类第一次加载的时候就会进行初始化,然后在实例化类时,会先执行初始化块,再执行构造函数。


                 修饰符的作用范围:public>protected>default>private

public:        当前类,当前包,子类,其他包

protected:当前类,当前包,子类

default:    当前类,当前包

private:    当前类


线程中,调用start()方法,是执行线程开启,这样才会并发执行,

              调用run()方法,只是简单的顺序调用


switch语句后的控制表达式只能是short、char、int、long整数类型和枚举类型,不能是float,double和boolean类型。

ps:String类型是java7开始支持的


DBMS中事务有四个特性:持久性,一致性,原子性,隔离性。

持久性------恢复管理子系统

一致性------并发控制子系统

原子性------完整性管理子系统

持久性------安全控制管理子系统


java包装类:Byte,Short,Integer,Long,Character,Double,Float,Boolean


Json对象:1.对象属性必须加双引号


JSP 四大作用域: page (作用范围最小)、requestsessionapplication(作用范围最大)。

  • 存储在application对象中的属性可以被同一个WEB应用程序中的所有Servlet和JSP页面访问。(属性作用范围最大)
  • 存储在session对象中的属性可以被属于同一个会话(浏览器打开直到关闭称为一次会话,且在此期间会话不失效)的所有Servlet和JSP页面访问。
  • 存储在request对象中的属性可以被属于同一个请求的所有Servlet和JSP页面访问(在有转发的情况下可以跨页面获取属性值),例如使用PageContext.forward和PageContext.include方法连接起来的多个Servlet和JSP页面。

存储在pageContext对象中的属性仅可以被当前JSP页面的当前响应过程中调用的各个组件访问,例如,正在响应当前请求的JSP页面和它调用的各个自定义标签类

jsp的9个内置对象: 
1、pageContext 表示页容器 EL表达式、 标签 、上传 
2、request 服务器端取得客户端的信息:头信息 、Cookie 、请求参数 ,最大用处在MVC设计模式上 
3、response 服务器端回应客户端信息:Cookie、重定向 
4、session 表示每一个用户,用于登录验证上 
5、application 表示整个服务器 
6、config 取得初始化参数,初始化参数在web.xml文件中配置 
7、exception 表示的是错误页的处理操作 
8、page 如同this一样,代表整个jsp页面自身 
9、out 输出 ,但是尽量使用表达式输出


考察点:抽象类和接口

相同点:都不能被实例化,位于继承树的顶端,都包含抽象方法

不同点:1、设计目的:接口体现的一种规范,类似与整个系统的总纲,制订了系统各模块应该遵循的标准,因此接口不应该经常改变,一旦改变对整个系统是辐射性的。

               抽象类作为多个子类的共同父类,体现的是一种模板式设计,可以当作系统实现过程中的中间产品,已经实现了系统部分功能。

            2、使用不同:(1)接口只能包含抽象方法,抽象类可以包含普通方法。

                                   (2)接口里不能定义静态方法,抽象类可以。

                                   (3)接口只能定义静态常量属性不能定义普通属性,抽象类可以。

                                   (4)接口不包含构造器,抽象类可以(不是用于创建对象而是让子类完成初始化)。

                                   (5)接口里不能包含初始化块,抽象类完全可以。

                                   (6)接口多继承,抽象类但继承(只能有一个直接父类)。

总结:接口所有方法全是抽象方法只能 public abstract修饰 (默认public abstract修饰 ),属性默认public static final修饰。

             抽象类除了包含抽象方法外与普通类无区别。


先编译:javac xxxx.java.产生字节码文件(xxxx.class). 再运行字节码文件: java xxxx 此时不需要加后缀


集合中线程安全的类有:vector,stack,hashtable,enumeration,除此之外均是非线程安全的类与接口


方法的重写(override)两同两小一大原则

方法名相同,参数类型相同

子类返回类型小于等于父类方法返回类型,

子类抛出异常小于等于父类方法抛出异常,

子类访问权限大于等于父类方法访问权限


JDK中提供了三个ClassLoader,根据层级从高到低为:

  1. Bootstrap ClassLoader,主要加载JVM自身工作需要的类。
  2. Extension ClassLoader,主要加载%JAVA_HOME%\lib\ext目录下的库类。
  3. Application ClassLoader,主要加载Classpath指定的库类,一般情况下这是程序中的默认类加载器,也是ClassLoader.getSystemClassLoader() 的返回值。(这里的Classpath默认指的是环境变量中配置的Classpath,但是可以在执行Java命令的时候使用-cp 参数来修改当前程序使用的Classpath)

JVM加载类的实现方式,我们称为 双亲委托模型

如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委托给自己的父加载器,每一层的类加载器都是如此,因此所有的类加载请求最终都应该传送到顶层的Bootstrap ClassLoader中,只有当父加载器反馈自己无法完成加载请求时,子加载器才会尝试自己加载。

双亲委托模型的重要用途是为了解决类载入过程中的安全性问题。

假设有一个开发者自己编写了一个名为Java.lang.Object的类,想借此欺骗JVM。现在他要使用自定义ClassLoader来加载自己编写的java.lang.Object类。然而幸运的是,双亲委托模型不会让他成功。因为JVM会优先在Bootstrap ClassLoader的路径下找到java.lang.Object类,并载入它


Servlet的生命周期分为5个阶段:加载、创建、初始化、处理客户请求、卸载。
(1)加载:Servlet容器(Tomcat)通过类加载器加载servlet文件(.class)
(2)创建:通过调用servlet构造函数创建一个servlet对象
(3)初始化:调用init方法初始化
(4)处理客户请求:每当有一个客户请求,容器会创建一个线程来处理客户请求
(5)卸载:调用destroy方法让servlet自己释放其占用的资源
servlet是由Servlet容器负责加载Servlet类,创建Servlet对象并实例化,然后调用Servlet的init方法,进行初始化,之后调用Service方法。实例化和初始化不同。先实例化,再初始化。


 


JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)

  • 栈区:
  1. 每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不是对象),对象都存放在堆区中
  2. 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
  3. 栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
  • 堆区:
  1. 存储的全部是对象实例,每个对象都包含一个与之对应的class的信息(class信息存放在方法区)。
  2. jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身,几乎所有的对象实例和数组都在堆中分配。
  • 方法区:
  1. 又叫静态区,跟堆一样,被所有的线程共享。它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

    PreparedStatement与Statement的区别

  2. 1.创建时的区别:  

        Statement statement = conn.createStatement();
        PreparedStatement preStatement = conn.prepareStatement(sql);
        执行的时候: 
        ResultSet rSet = statement.executeQuery(sql);
        ResultSet pSet = preStatement.executeQuery();

    由上可以看出,PreparedStatement有预编译的过程,已经绑定sql,之后无论执行多少遍,都不会再去进行编译,

    而 statement 不同,如果执行多变,则相应的就要编译多少遍sql,所以从这点看,preStatement 的效率会比 Statement要高一些

    1. 2.安全性问题

      这个就不多说了,preStatement是预编译的,所以可以有效的防止 SQL注入等问题

      所以 preStatement 的安全性 比 Statement 高

      3.代码的可读性 和 可维护性 


      表达式的数据类型自动提升, 关于类型的自动提升,注意下面的规则。

      ①所有的byte,short,char型的值将被提升为int型;

      ②如果有一个操作数是long型,计算结果是long型;

      ③如果有一个操作数是float型,计算结果是float型;

      ④如果有一个操作数是double型,计算结果是double型;


      客户端通过new socket()来创建socket对象,服务器端通过new serverSocket()来创建tcp连接对象,通过accept方法获得客户端请求


      orward和redirect是最常问的两个问题

      forward,服务器获取跳转页面内容传给用户,用户地址栏不变

      redirect,是服务器向用户发送转向的地址,redirect后地址栏变成新的地址


      round函数是取最接近整数,如果遇到一样近,则取最大值。


      main()函数即主函数,是一个前台线程,前台进程是程序中必须执行完成的,而后台线程则是java中所有前台结束后结束,不管有没有完成,后台线程主要用与内存分配等方面。                                                                                           
       前台线程和后台线程的区别和联系:

      1、后台线程不会阻止进程的终止。属于某个进程的所有前台线程都终止后,该进程就会被终止。所有剩余的后台线程都会停止且不会完成。
      2、可以在任何时候将前台线程修改为后台线程,方式是设置Thread.IsBackground 属性。
      3、不管是前台线程还是后台线程,如果线程内出现了异常,都会导致进程的终止。

      4、托管线程池中的线程都是后台线程,使用new Thread方式创建的线程默认都是前台线程。
      说明:   

              应用程序的主线程以及使用Thread构造的线程都默认为前台线程                       
          使用Thread建立的线程默认情况下是前台线程,在进程中,只要有一个前台线程未退出,进程就不会终止。主线程就是一个前台线程。而后台线程不管线程是否结束,只要所有的前台线程都退出(包括正常退出和异常退出)后,进程就会自动终止。一般后台线程用于处理时间较短的任务,如在一个Web服务器中可以利用后台线程来处理客户端发过来的请求信息。而前台线程一般用于处理需要长时间等待的任务,如在Web服务器中的监听客户端请求的程序,或是定时对某些系统资源进行扫描的程序


      静态的include:是jsp的指令来实现的,<% @ include file="xx.html"%> 特点是 共享request请求域,先包含再编译,不检查包含页面的变化。

      动态的include:是jsp动作来实现的,<jsp:include page="xx.jsp" flush="true"/>  这个是不共享request请求域,先编译在包含,是要检查包含页面的变化的。


       

    2. 题目:-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3

    3. -Xmx10240m:代表最大堆

       -Xms10240m:代表最小堆

       -Xmn5120m:代表新生代

       -XXSurvivorRatio=3:代表Eden:Survivor = 3    根据Generation-Collection算法(目前大部分JVM采用的算法),一般根据对象的生存周期将堆内存分为若干不同的区域,一般情况将新生代分为Eden ,两块Survivor;    计算Survivor大小, Eden:Survivor = 3,总大小为5120,3x+x+x=5120  x=1024

      新生代大部分要回收,采用Copying算法,快!

      老年代 大部分不需要回收,采用Mark-Compact算法


      HashTable和HashMap区别

      ①继承不同。

      public class Hashtable extends Dictionary implements Map public class HashMap extends AbstractMap implements Map

      Hashtable 中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

      Hashtable中,key和value都不允许出现null值。

      在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

      ④两个遍历方式的内部实现上不同。

      Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

      哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

      Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。


      1,新生代:(1)所有对象创建在新生代的Eden区,当Eden区满后触发新生代的Minor GC,将Eden区和非空闲Survivor区存活的对象复制到另外一个空闲的Survivor区中。(2)保证一个Survivor区是空的,新生代Minor GC就是在两个Survivor区之间相互复制存活对象,直到Survivor区满为止。
      2,老年代:当Survivor区也满了之后就通过Minor GC将对象复制到老年代。老年代也满了的话,就将触发Full GC,针对整个堆(包括新生代、老年代、持久代)进行垃圾回收。
      3,持久代:持久代如果满了,将触发Full GC。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值