zoukankan      html  css  js  c++  java
  • 一点题目(一)

    1,switch语句能否作用在byte上,能否作用在long上,能否作用在String上?

      在jdk1.6之前,在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。显然,long和String类型都不符合switch的语法规定,并且不能被隐式转换成int类型,所以,它们不能作用于swtich语句中。

      今天自己动手之后发现

      switch("s")出现提示:Cannot switch on a value of type String for source level below 1.7. Only convertible int values or enum constants are permitted。

    2,short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;

      在动手之前自己想当然的以为是:s1 + 1会自己强制转换为short,但其实不然。

      Java数据类型的转换,分为自动转换和强制转换。

      自动转换时在程序执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换;例如:

      short s1 = 1;

      int s2 = s1;

      强制类型转换则必须在代码中声明,转换顺序不受限制。 

      int s1 = 1;

      short s2 = (int)s1;

      题目中的“+=”是java语言规定的运算符,java编辑器会对它进行特殊处理,因此可以正常编译。

    3,使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。
    4,Servlet

    概念:

      全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态web内容。狭义的Servlet是指Java语言实现的一个接口,广义的servlet是指任务实现了这个Servlet的类。

      servlet运行于支持Java的应用服务器中。从实现上讲,servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

    工作模式:

      客户端发送请求到服务器;

      服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器;

      服务器将响应返回客户端;

    HttpServlet:

      javax.servlet.http.HttpServlet实现了专门用于响应HTTP请求的Servlet,提供了响应对应HTTP标准请求的doGet()、doPost()等方法。

    生命周期:

      当servlet被部署在应用服务器中(应用服务器中用于管理Java组件的部分被抽象成为容器)以后,由容器控制servlet的生命周期。除非特殊指定,否则在容器启动的时候,servlet是不会被加载的,servlet只会在第一次请求的时候被加载和实例化。servlet一旦被加载,一般不会从容器中删除,直至应用服务器关闭或重新启动。但当容器做内存回收动作时,servlet有可能被删除。也正是因为这个原因,第一次访问servlet所用的时间要大大多于以后访问所用的时间。

      servlet在服务器的运行生命周期为,在第一次请求(或其实体被内存垃圾回收后再被访问)时被加载并执行一次初始化方法,跟着执行正式运行方法,之后会被常驻并每次被请求时直接执行正式运行方法,直到服务器关闭或被清理时执行一次销毁方法后实体销毁。

    5,run方法和start方法

      start方法

      用start方法来启动线程,是真正实现了多线程,通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。但要注意的是,此时无需等待run()方法执行完毕,即可继续执行下面的代码。所以run()方法并没有实现多线程。
      run方法

      run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码。

    6,HttpSession session = request.getSession(false) 与HttpSession session = request.getSession(true)的区别?

    HttpSession session = request.getSession(boolean create) ;
    返回当前请求的会话,如果当前请求不属于任何会话,而且create参数为true,则创建一个会话,否则返回null。此后所有来自同一个请求都属于这个会话,通过它的getSession返回的是当前会话。

    7,String和StringBuffer的区别

    (1)String是不可变的对象,StringBuffer是可以再编辑的;
    (2)String是常量,StringBuffer是变量;
    (3)String、StringBuffer、StringBuilder
    String 字符串常量
    StringBuffer 字符串变量(线程安全)
    StringBuilder 字符串变量(非线程安全)
    String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都是String类的对象。字符串是常量;它们的值在创建之后不能改变。所以可以共享它们。StringBuffer是字符串缓存区,它的内容可以被修改,长度也可以改变,StringBuffer类是线程安全的,也就是说多个线程可以安全的访问StringBuffer对象。StringBuilder与StringBuffer类似,都是字符串缓冲区,但StringBuilder不是线程安全的,如果你只是在单线程中使用字符串缓冲区,那么StringBuilder的效率会更高些。值得注意的是StringBuilder是在JDK1.5版本中增加的。以前版本的JDK不能使用该类。

    8,JVM的垃圾回收方式:

    jvm性能调优/垃圾回收器


    9,在Java中,声明一个数组时,不能直接限定数组长度,只有在创建实例化对象时,才能给定数组长度。

    例如:String a[] = new String[50]; String b[];char c[]; 是对的,String d[50]; char a[50];是错的

    10,Java关于继承的描述

    (1)一个子类只能继承一个父类
    (2)继承具有传递性
    (3)父类一般具有通用性,子类更具体
    (4)子类可以继承父类的构造方法(错误)
    (5)在java中,子类构造器会默认调用super()(无论构造器中是否写有super()),用于初始化父类成员,同时当父类中存在有参构造器时,必须提供无参构造器,子类构造器中并不会自动继承有参构造器,仍然默认调用super(),使用无参构造器。因此,一个类想要被继承必须提供无参构造器。
    (6)方法没有继承一说,只有重载和重写

    11,Servlet的生命周期一般可以用三个方法来表示:

    init():仅执行一次,负责在装载Servlet时初始化Servlet对象
    service():核心方法,一般HttpServlet中会有get,post两种处理方式。在调用doGet和doPost方法时会构造servletRequest和servletResponse请求和响应对象作为参数。
    destory():在停止并且卸载Servlet时执行,负责释放资源
    初始化阶段:Servlet启动,会读取配置文件中的信息,构造指定的Servlet对象,创建ServletConfig对象,将ServletConfig作为参数来调用init()方法。所以选ACD。B是在调用service方法时才构造的

    12,String str = new String(“abc”),“abc”在内存中是怎么分配的?

    堆和字符串常量区
    参考:
    什么是字符串常量池
    JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池

    工作原理
    当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。

    实现前提
    字符串常量池实现的前提条件就是Java中String对象是不可变的,这样可以安全保证多个变量共享同一个对象。如果Java中的String对象可变的话,一个引用操作改变了对象的值,那么其他的变量也会受到影响,显然这样是不合理的。

    更详细的关于字符串常量池 http://droidyue.com/blog/2014/12/21/string-literal-pool-in-java/

    关于堆和栈
    Java中所有由类实例化的对象和数组都存放在堆内存中,无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。而栈内存用来存储局部变量和方法调用。
    更详细的关于堆和栈的区别 http://droidyue.com/blog/2014/12/07/differences-between-stack-and-heap-in-java/

    关于寄存器
    Java中运行时数据区有一个程序寄存器(又称程序计数器),该寄存器为线程私有。Java中的程序计数器用来记录当前线程中正在执行的指令。如果当前正在执行的方法是本地方法,那么此刻程序计数器的值为undefined
    关于JVM运行时数据区的 http://droidyue.com/blog/2014/12/21/java-runtime-data-areas/

    关于本题目中,"abc"为字面量对象,其存储在堆内存中。而字符串常量池则存储的是字符串对象的一个引用。

    13,request的forward和response的redirect

    1.redirect地址栏变化,forward发生在服务器端内部从而导致浏览器不知道响应资源来自哪里
    2.redirect可以重定向到同一个站点上的其他应用程序中的资源,forward 只能将请求 转发给同一个WEB应用中的组件
    3.redirect默认是302码,包含两次请求和两次响应
    4.redirect效率较低

    14,代码片段

    byte b1=1,b2=2,b3,b6;
    final byte b4=4,b5=6;
    b6=b4+b5;
    b3=(b1+b2);
    System.out.println(b3+b6);
    解析:
    语句:b3=b1+b2编译出错,被final修饰的变量是常量,这里的b6=b4+b5可以看成是b6=10;在编译时就已经变为b6=10了
    而b1和b2是byte类型,java中进行计算时候将他们提升为int类型,再进行计算,b1+b2计算后已经是int类型,赋值给b3,b3是byte类型,类型不匹配,编译不会通过,需要进行强制转换。
    Java中的byte,short,char进行计算时都会提升为int类型。

    15,volatile关键字

    (1)用volatile修饰的变量,每次更新对其他线程都是立即可见的。
    (2)对volatile变量的操作是原子性的。(错误)
    (3)对volatile变量的操作不会造成阻塞。
    (4)不依赖其他锁机制,多线程环境下的计数器可用volatile实现。(错误)
    一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
    1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
    2)禁止进行指令重排序。
    volatile只提供了保证访问该变量时,每次都是从内存中读取最新值,并不会使用寄存器缓存该值——每次都会从内存中读取。
    而对该变量的修改,volatile并不提供原子性的保证。
    由于及时更新,很可能导致另一线程访问最新变量值,无法跳出循环的情况
    多线程下计数器必须使用锁保护。

  • 相关阅读:
    24张图,九大数据结构安排得明明白白
    mysql中的mvcc解读
    常见电商项目的数据库表设计(MySQL版)
    两万字深度介绍分布式系统原理,一文入魂
    使用消息中间件时,如何保证消息仅仅被消费一次?
    GCC/G++选项 -Wl,-Bstatic和-Wl,-Bdynamic
    sql 练习
    设计模式-单例模式
    设计模式-抽象工厂模式
    设计模式-工厂方法模式
  • 原文地址:https://www.cnblogs.com/lemon-now/p/5147409.html
Copyright © 2011-2022 走看看