牛客刷题笔记--(java基础1-50)

1 关于对象成员占用内存的说法哪个正确?( )
同一个类的对象共用同一段内存

同一个类的对象使用不同的内存段,但静态成员共享相同的内存空间

对象的方法不占用内存

以上都不对

当你创建一个新的实例对象时,它会得到一块新的内存空间。但是类中的静态成员变量是所有对象共有的,也就是在一片属于类的存储空间中,被所有对象共有。每一个对象在堆中都有各自的内存区域,静态变量是所有对象共有的。
静态成员属于类成员,在方法区分配内存,而不是堆。静态变量属于类本身,成员变量属于类的某个实例
牛客刷题笔记--(java基础1-50)_第1张图片
2 在类Tester中定义方法如下,

public double max(int x, int y) { // 省略 }

则在该类中定义如下哪个方法头是对上述方法的重载(Overload)?
牛客刷题笔记--(java基础1-50)_第2张图片 重载就是一句话:同名不同参,返回值无关。
覆盖/重写:同名同参

Java 重载的规则:

1、必须具有不同的参数列表;

2、可以有不同的返回类型,只要参数列表不同就可以;

3、可以有不同的访问修饰符;

4、可以抛出不同的异常;

5、方法能够在一个类中或者在一个子类中被重载

方法的重写:

1、在子类中可以根据需要对从基类中继承来的方法进行重写。

2、重写的方法和被重写的方法必须具有相同方法名称、参数列表和返回类型。

3、重写方法不能使用比被重写的方法更严格的访问权限

3 关于依赖注入,下列选项中说法错误的是()
依赖注入能够独立开发各组件,然后根据组件间关系进行组装
依赖注入使组件之间相互依赖,相互制约(B错误,依赖注入的动机就是减少组件之间的耦合度,使开发更为简洁)
依赖注入提供使用接口编程
依赖注入指对象在使用时动态注入

依赖注入和控制反转
依赖注入和控制反转是同一概念:

    依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。

SQL语言又称为结构化查询语言
java中”static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问
java是强类型语言,javascript是弱类型语言
面向对象的三大特性包括:封装,继承,多态
值传递,传递的是原来值的副本。
引用传递,除了一些特殊的(String,包装类属于不可变类),一般的引用类型在进行传递的时候,一开始形参和实参都是指向同一个地址的,这个时候形参对对象的改变会影响到实参。

传值传参的时候,我们在函数中改变了参数的值,其对应的变量的值并不改变,值类型传参就是将变量保存的内容复制到函数的形参中,他们是两个不同的变量,只不过保存的内容相同罢了.
引用传参保存的是一个地址,这个地址里保存的是变量的具体值,而引用类型作为参数的时候,是将变量保存的地址值赋值到参数变量里,这样他们都指向了同一个内容,这样我们改变参数的成员的话,那么相应的变量的成员也会改变。

4看以下代码: 文件名称:forward.jsp 如果运行以上jsp文件,地址栏的内容为

<html>  
     <head><title> 跳转  </title> </head> 
     <body>  
         <jsp:forward page="index.htm"/>     
     </body>
 </html> 

牛客刷题笔记--(java基础1-50)_第3张图片
redirect:请求重定向:客户端行为,本质上为2次请求,地址栏改变,前一次请求对象消失。举例:你去银行办事(forward.jsp),结果告诉你少带了东西,你得先去局办(index.html)临时身份证,这时你就会走出银行,自己前往***局,地址栏变为index.html.
forward:请求转发:服务器行为,地址栏不变。举例:你把钱包落在出租车上,你去警察局(forward.jsp)报案,警察局说钱包落在某某公司的出租车上(index.html),这时你不用亲自去找某某公司的出租车,警察局让出租车自己给你送来,你只要在警察局等就行。所以地址栏不变,依然为forward.jsp

5 关于中间件特点的描述.不正确的是()
中间件运行于客户机/服务器的操作系统内核中,提高内核运行效率(错误)
中间件应支持标准的协议和接口
中间件可运行于多种硬件和操作系统平台上
跨越网络,硬件,操作系统平台的应用或服务可通过中间件透明交互

中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件。相连接的系统,即使它们具有不同的接口,但通过中间件相互之间仍能交换信息。执行中间件的一个关键途径是信息传递。通过中间件,应用程序可以工作于多平台或OS环境。
(简单来说,中间件并不能提高内核的效率,一般只是负责网络信息的分发处理)

中间件位于操作系统之上,应用软件之下,而不是操作系统内核中

AWT和Swing都是java中的包。

AWT(Abstract Window Toolkit):抽象窗口工具包,早期编写图形界面应用程序的包。

Swing :为解决 AWT 存在的问题而新开发的图形界面包。Swing是对AWT的改良和扩展。

线程安全的map:HashTable,Synchronized Map,ConcurrentHashMap

Hashtable是线程安全的哈希表,它是通过synchronized来保证线程安全的;即,多线程通过同一个“对象的同步锁”来实现并发控制。Hashtable在线程竞争激烈时,效率比较低(此时建议使用ConcurrentHashMap)。当一个线程访问Hashtable的同步方法时,其它线程如果也在访问Hashtable的同步方法时,可能会进入阻塞状态。 

Collections.synchronizedMap()使用了synchronized同步关键字来保证对Map的操作是线程安全的。 

ConcurrentHashMap是线程安全的哈希表。在JDK1.7中它是通过“锁分段”来保证线程安全的,本质上也是一个“可重入的互斥锁”(ReentrantLock)。多线程对同一个片段的访问,是互斥的;但是,对于不同片段的访问,却是可以同步进行的。在JDK1.8中是通过使用CAS原子更新、volatile关键字、synchronized可重入锁实现的。 

6 servlet周期包含哪些:

Servlet生命周期分成3个阶段:

1)初始化阶段:调用init方法

2)响应客户请求:调用service

3)终止:调用destory方法

7 局部内部类可以用哪些修饰符修饰?
牛客刷题笔记--(java基础1-50)_第4张图片

局部内部类是放在代码块或方法中的,不能有访问控制修饰符,且不能用static修饰
牛客刷题笔记--(java基础1-50)_第5张图片8以下的变量定义语句中,合法的是()
byte a=128(×) byte能表示的范围[-128,127]
boolean flag =null; (×)boolean的取值只能是true或false
long a=123L ; (√)
float f = 0.9239 ; (×)0.9239为double类型
double=0.9239d(√)
9针对下面的代码块,哪个equal为true:(A)

String s1 = "xiaopeng" ;
String s2 = "xiaopeng" ;
String s3 =new String (s1);

选项
s1 == s2
s1 = s2
s2 == s3
都不正确
解释
string是final修饰的,会将创建的变量放入字符串常量池,当再创建同样的字符串时,发现常量池中有则直接使用 。String s 1 = “xiaopeng”,这种定义字符串的方式,首先看看字符串常量池中是否有“xiaopeng"如果有就就直接从常量池中取,没有则将“xiaopeng"放到常量池中。String s2 = 'xiaopeng",常量池中有”xiaopeng",直接取值。string s3 = new String(“xiaopeng”);直接在堆中产生一个字符串“xiaopeng”.所以s1和s2地址一样,和s3地址不一样
String有两种实例化方式:直接赋值 使用new关键字
两种实例化方式比较:直接赋值只会开辟一块堆内存空间,并且会自动保存在常量池
构造法开辟两块堆内存空间,不会自动入池,其中一块将成为垃圾,可以用 intern()方法手动入池
10 对于application,主线程main()方法执行的线索,对于applet,主线程是浏览器加载并执行java小程序。(√)
11 下列关于修饰符混用的说法,错误的是(D )
abstract不能与final并列修饰同一个类
abstract 类中不建议有private的成员
abstract 方法必须在abstract类或接口中
static方法中能直接处理非static的属性

A abstract修饰的类,不可实例化,所以需要子类去继承,然后重写其中的抽象方法。但是final修饰类是不可继承的。两者属性相冲。
B、看清楚,人家说的是不建议有,不是不能有。
C、抽象类中可以没有抽象方法,但是抽象方法必须在抽象类中或者接口中
D、static不可以修饰非static的属性,因为类加载的时候,static属性比非static先初始化,那么一个存在的总不能访问一个没有存在的吧。

不管是静态方法还是静态成员,都是类级别存在的,也就是说随着类的加载而加载,优先于对象的存在,而非静态成员和方法是对象级别的存在,所以在静态方法中调用非静态的成员或方法(此时还不存在对象),是不可能的,但是反过来是可以的:非静态中调用静态。于是也就有静态方法中不能使用this和super关键字。

12 以下描述错误的一项是( C)?
程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行 到了第几行,是线程隔离的
原则上讲,所有的对象都是在堆区上分配内存,是线程之间共享的
方法区用于存储JVM加载的类信息、常量、静态变量,即使编译器编译后的代码等数据,是线程隔离的
Java方法执行内存模型,用于存储局部变量,操作数栈,动态链接,方法出口等信息,是线程隔离的

解释

JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)
栈区:每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不是对象),对象都存放在堆区中。每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

堆区: 存储的全部是对象实例,每个对象都包含一个与之对应的class的信息(class信息存放在方法区)。
jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身,几乎所有的对象实例和数组都在堆中分配。
方法区: 又叫静态区,跟堆一样,被所有的线程共享。它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

牛客刷题笔记--(java基础1-50)_第6张图片 方法区和堆内存是线程共享的。
程序计数器、虚拟机栈是线程隔离的

13子类A继承父类B, A a = new A(); 则父类B构造函数、父类B静态代码块、父类B非静态代码块、子类A构造函数、子类A静态代码块、子类A非静态代码块 执行的先后顺序是?

答:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数

解释
正确的执行顺序是:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数
也就是说非静态初始化块的执行顺序要在构造函数之前。
当实例化子类对象时,首先要加载父类的class文件进内存,静态代码块是随着类的创建而执行,所以父类静态代码块最先被执行,子类class文件再被加载,同理静态代码块被先执行;实例化子类对象要先调用父类的构造方法,而调用父类构造方法前会先执行父类的非静态代码块
会先执行静态代码块,因为静态代码块是类级别的,是在创建对象之前就执行的。因为子类继承了父类,所以父类的静态代码块会先执行,接着执行子类的静态代码块。

因为构造函数可能要给动态代码块的一些成员变量赋值,所以必须在这之前先执行动态代码块,要不然构造函数会出现相关的成员属性无定义。所以会先执行动态代码块,在执行构造函数。一般先按父类的执行,再按子类的执行。
14 对于构造方法,下列叙述正确的是( ACD)。
构造方法的优先级一般比代码块低。
构造方法的返回类型只能是void型。(×)
构造方法的主要作用是完成对类的对象的初始化工作。
一般在创建新对象时,系统会自动调用构造方法。
解释
B think in java中提到构造器本身并没有任何返回值。
构造方法的特点: 构造方法的方法名与类名相同
构造方法没有返回值类型,也不写void
构造方法可以重载
什么时候会用到构造方法:
在创建对象的时候
构造方法的作用:
创建对象的时候给属性赋初值
构造方法的分类:
显示的构造方法和隐式地构造方法
显示的构造方法:显示的写出构造方法时,系统不会提供默认的无参构造方法
隐式地构造方法:系统默认提供的无参构造方法
代码块:
分类:静态代码块和实例代码块
静态代码块:static修饰的代码块,在类加载时执行,且只执行一次。因为类就加载一次了。
实例代码块:没有static修饰的代码块,创建对象时执行,每创建一次对象加载一次。
实例代码块在执行构造方法之前执行。所以优先级高于构造方法。

15 将类的成员的访问权限设置为默认的,则该成员能被(A )
同一包中的类访问
其它包中的类访问
所有的类访问
所有的类的子类访问

解释
public:可以被所有其他类所访问;
protected:自身、子类及同一个包中类可以访问;
default:同一包中的类可以访问;
private:只能被自己访问和修改。
public>protcted>default>priavte
牛客刷题笔记--(java基础1-50)_第7张图片每一个和.java文件同名的public类可以有多个构造方法,构造方法允许重载。内部类也可以有多个构造方法,而匿名内部类一个构造方法都没有。

子类使用super调用父类构造方法是,也是在创建对象的过程中 。创建子类的对象时,会先执行父类的构造函数。
一个类可以有多个构造方法,多个构造方法通过不同参数列表进行重载。

16 关于抽象类叙述正确的是? (B )
抽象类不能实现接口
抽象类必须有“abstract class”修饰
抽象类必须包含抽象方法
抽象类也有类的特性,可以被实例化
解释
A.抽象类是可以实现接口的,而且抽象类也可以继承自抽象类
抽象类指有abstract修饰的class,其可以包含抽象方法,也可以不包含
抽象类和接口都是不能被实例化的,只有具体的类才可以被实例化

jdk1.8之前

接口

1.多实现

2.变量类型默认且只能为为public static final

3.函数类型默认且只能为public,只能有public类型的静态成员函数

4.非静态成员函数没有方法体,静态成员函数有方法体

5.子类必须实现所有接口函数(抽象子类可以不实现接口的全部接口函数)

6.可以有main方法;可以new一个接口,需要在方法体中实现所有接口函数

7.没有构造器

抽象类

1.单继承

2.变量类型不限(静态变量+非静态变量)

3.函数类型不限(静态函数+非静态函数)

4.非静态函数包含没有方法体的抽象函数. 有方法体的普通函数

5.子类可以不覆写父类的抽象方法,但子类也要申明为抽象类;子类可以选择覆写父类的非抽象方法

6.可以有main方法;不可以new一个抽象类

7.可以有构造器

Jdk1.8

接口中可以有default类型的方法,实现类可以选择实现该方法

意义:默认方法的主要优势是提供一种拓展接口的方法,而不破坏现有代码。另一个优势为该方法是可选的,子类可以根据不同的需求Override或默认实现。

17 在为传统面向对象语言的程序做单元测试的时候,经常用到mock对象。Mock对象通过反射数。请问反射最大程度破坏了面向对象的以下哪个特性?(封装)

反射破坏代码的封装性,破坏原有的访问修饰符访问限制

mock对象:也成为伪对象,在测试中的利用mock对象来代替真实对象,方便测试的进行。
java的封装性:指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,通过该类提供的方法实现对内部信息的操作访问。
反射机制:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性
反射可以访问原类的私有方法,私有成员变量,因此,反射破坏了Java的封装性

18 @SuppressWarnings(“deprecation”)的功能是什么?
答:屏蔽不赞同使用的类和方法的警告
解释
Override 注解
指明被注解的方法需要覆写超类中的方法.
如果某个方法使用了该注解,却没有覆写超类中的方法(比如大小写写错了,或者参数错了,或者是子类自己定义的方法),编译器就会生成一个错误.

Deprecated 注解

可以修饰类、方法、变量,在java源码中被@Deprecated修饰的类、方法、变量等表示不建议使用的,可能会出现错误的,可能以后会被删除的类、方法等,如果现在使用,则在以后使用了这些类、方法的程序在更新新的JDK、jar包等就会出错,不再提供支持。 个人程序中的类、方法、变量用@Deprecated修饰同样是不希望自己和别人在以后的时间再次使用此类、方法。 当编译器编译时遇到了使用@Deprecated修饰的类、方法、变量时会提示相应的警告信息。

Suppresswarnings 注解
可以达到抑制编译器编译时产生警告的目的,但是很不建议使用@SuppressWarnings注解,使用此注解,编码人员看不到编译时编译器提示的相应的警告,不能选择更好、更新的类、方法或者不能编写更规范的编码。同时后期更新JDK、jar包等源码时,使用@SuppressWarnings注解的代码可能受新的JDK、jar包代码的支持,出现错误,仍然需要修改。

19 以下程序的输出结果为(D)

class Base{
    public Base(String s){
        System.out.print("B");
    }
}
public class Derived extends Base{
    public Derived (String s) {
        System.out.print("D");
    }
    public static void main(String[] args){
        new Derived("C");
    }
}

选项
BD
DB
C
编译错误

解释
java初始化顺序。初始化子类必先初始化父类。子类的构造方***隐式去调用 父类无参的构造方法(不会在代码中显示)。但如果父类没有无参的构造方法,就必须在子类构造方法第一行显示调用父类的有参构造方法。否则编译失败
在调用子类构造器之前,会先调用父类构造器,当子类构造器中没有使用"super(参数或无参数)"指定调用父类构造器时,是默认调用父类的无参构造器,如果父类中包含有参构造器,却没有无参构造器,则在子类构造器中一定要使用“super(参数)”指定调用父类的有参构造器,不然就会报错。

20Gadget has-a Sprocket and Gadget has-a Spring and Gadget is-a Widget and Widget has-a
Sprocket 以下哪两段代码可以表示这个关系? (选择两项) ( AC )

class Widget { Sprocket s; }
class Gadget extends Widget { Spring s; }
class Widget { }
class Gadget extends Widget { Spring s1; Sprocket s2; }
class Widget { Sprocket s1; Spring s2; }
class Gadget extends Widget { }
class Gadget { Spring s; }
class Widget extends Gadget{ Sprocket s; }

解释
is-a 表示继承:Gadget is-a Widget就表示Gadget 继承 Widget;
has-a表示从属:Gadget has-a Sprocket就表示Gadget中有Sprocket的引用,Sprocket是Gadget的组成部分;
like-a表示组合:如果A like-a B,那么B就是A的接口

21关于抽象类与接口,下列说法正确的有?(AC)

优先选用接口,尽量少用抽象类
抽象类可以被声明使用,接口不可以被声明使用
抽象类和接口都不能被实例化。
以上说法都不对
解释
含有abstract修饰符的class即为抽象类,abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class
类中定义抽象方法必须在具体
(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。

接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。

总结了一下

  1. 一个子类只能继承一个抽象类,但能实现多个接口
  2. 抽象类可以有构造方法,接口没有构造方法
  3. 抽象类可以有普通成员变量,接口没有普通成员变量
  4. 抽象类和接口都可有静态成员变量,抽象类中静态成员变量访问类型任意,接口只能public static final(默认)
  5. 抽象类可以没有抽象方法,抽象类可以有普通方法,接口中都是抽象方法
  6. 抽象类可以有静态方法,接口不能有静态方法
  7. 抽象类中的方法可以是public、protected;接口方法只有public

java只是单继承,但是可以实现多个接口,继承的耦合性太强,java推荐高内聚低耦合的设计思路,不推荐使用继承。在用继承的情况下,如果还必须要继承另外的接口会很麻烦,尽量用接口,这样在你必须要用到继承的时候就可以用了。抽象类和接口都不能被实例化。接口没有构造方法,不能被实例化,但是抽象方法可以有构造方法,不过不是用来实例化对象的,使用来初始化的。
22 对 Map 的用法,正确的有(DC):

new java.util.Map().put("key" , "value") ;
new java.util.SortedMap().put("key" , "value") ;
new java.util.HashMap().put( null , null ) ;
new java.util.TreeMap().put( 0 , null ) ;

Map家族的继承实现关系如下,注意一点就是顶层的Map接口与Collection接口是依赖关系:
牛客刷题笔记--(java基础1-50)_第8张图片关于Key和Value能否为null的问题:
牛客刷题笔记--(java基础1-50)_第9张图片
Map和SortedMap是接口,不能直接new对象,A,B错误
HashMap 允许null-null键值对 C正确
TreeMap 允许value值为null,不允许key值为null,D是value为null,key不为null,正确

23 对于java类型变量char c,short s,float f,double d,表达式c*s+f+d的结果类型为(D)
float
char
short
double

char 2字节 short 2字节 float 4字节 double 8字节往精度高的转
基本数据类型的运算,会自动向上转型。boolean不可以和其他基本数据类型相互转换。
byte->short,char -> int -> long
float -> double
int -> float
long -> double
牛客刷题笔记--(java基础1-50)_第10张图片 24关于抽象类和接口叙述正确的是? (D )
抽象类和接口都能实例化的
抽象类不能实现接口
抽象类方法的访问权限默认都是public
接口方法的访问权限默认都是public
解释
抽象类和方法都不能被实例化
2、抽象类可以实现接口
3、抽象类方法默认访问权限都是default
4、接口就是访问的,默认访问权限都是public

抽象类

特点:
1.抽象类中可以构造方法
2.抽象类中可以存在普通属性,方法,静态属性和方法。
3.抽象类中可以存在抽象方法。
4.如果一个类中有一个抽象方法,那么当前类一定是抽象类;抽象类中不一定有抽象方法。
5.抽象类中的抽象方法,需要有子类实现,如果子类不实现,则子类也需要定义为抽象的。
6,抽象类不能被实例化,抽象类和抽象方法必须被abstract修饰

关键字使用注意:
抽象类中的抽象方法(其前有abstract修饰)不能用private、static、synchronized、native访问修饰符修饰。
接口

1.在接口中只有方法的声明,没有方法体。
2.在接口中只有常量,因为定义的变量,在编译的时候都会默认加上public static final
3.在接口中的方法,永远都被public来修饰。
4.接口中没有构造方法,也不能实例化接口的对象。(所以接口不能继承类)
5.接口可以实现多继承
6.接口中定义的方法都需要有实现类来实现,如果实现类不能实现接口中的所有方法则实现类定义为抽象类。
7,接口可以继承接口,用extends

25 ArrayList和Vector主要区别是什么?
答:Vector与ArrayList一样,也是通过数组实现的,不同的是Vector支持线程的同步
Vector & ArrayList 的主要区别
1) 同步性:Vector是线程安全的,也就是说是同步的 ,而ArrayList 是线程序不安全的,不是同步的
2)数据增长:当需要增长时,Vector默认增长为原来一倍 ,而ArrayList却是原来的50% ,这样,ArrayList就有利于节约内存空间。
如果涉及到堆栈,队列等操作,应该考虑用Vector,如果需要快速随机访问元素,应该使用ArrayList 。

扩展知识:

  1. Hashtable & HashMap
    Hashtable和HashMap它们的性能方面的比较类似 Vector和ArrayList,比如Hashtable的方法是同步的,而HashMap的不是。

  2. ArrayList & LinkedList

ArrayList的内部实现是基于内部数组Object[],所以从概念上讲,它更象数组,但LinkedList的内部实现是基于一组连接的记录,所以,它更象一个链表结构,所以,它们在性能上有很大的差别:
从上面的分析可知,在ArrayList的前面或中间插入数据时,你必须将其后的所有数据相应的后移,这样必然要花费较多时间,所以,当你的操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能; 而访问链表中的某个元素时,就必须从链表的一端开始沿着连接方向一个一个元素地去查找,直到找到所需的元素为止,所以,当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
26 JDK1.8版本之前,抽象类和接口的区别,以下说法错误的是(D)
A接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的。

Babstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface,实现多重继承。接口还有标识(里面没有任何方法,如Remote接口)和数据共享(里面的变量全是常量)的作用。

C在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是 static final的,不过在 interface中一般不定义数据成员),所有的成员方法默认都是 public abstract 类型的。

Dabstract class和interface所反映出的设计理念不同。其实abstract class表示的是"has-a"关系,interface表示的是"is-a"关系。

解释
is-a:继承关系 has-a:从属关系 like-a:组合关系
abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。
接口可以继承接口,而且可以继承多个接口,但是不能实现接口,因为接口中的方法全部是抽象的,无法实现;
另外,如果是Java 7以及以前的版本,那么接口中可以包含的内容有:1. 常量;2. 抽象方法
如果是Java 8,还可以额外包含有:3. 默认方法;4. 静态方法
如果是Java 9,还可以额外包含有:5. 私有方法
2)普通类可以实现接口,并且可以实现多个接口,但是只能继承一个类,这个类可以是抽象类也可以是普通类,如果继承抽象类,必须实现抽象类中的所有抽象方法,否则这个普通类必须设置为抽象类;

3)抽象类可以实现接口,可以继承具体类,可以继承抽象类,也可以继承有构造器的实体类。
抽象类中可以有静态main方法;抽象类里可以没有抽象方法,没有抽象方法的抽象类就是不想让别人实例化它;
另外,抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已。在继承了抽象类的子类中通过super(参数列表)调用抽象类中的构造方法,可以用于实例化抽象类的字段。

下面总结常见的抽象类与接口的区别:
1)抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象;
2)接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现(java8中 接口可以有实现方法 使用default修饰);
3)接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量;
4)抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个类实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类;
5)抽象方法要被实现,所以不能是静态static的,也不能是私有private的,也不能被final修饰(试想一下,静态方法可以被类名直接调用,而类名直接调用一个没有实现的抽象方法没有意义)。

接口与抽象类是不同的概念。抽象类是用于捕捉子类的通用特性,接口是抽象方法的集合;
实现接口必须实现接口的所有方法;
接口可以继承一个或多个接口,抽象类只能继承一个类或者实现多个接口;
一个类只能继承一个类,但是可以实现多个接口。

27 下面的对象创建方法中哪些会调用构造方法 (AC)?
new语句创建对象
调用Java.io.ObjectInputStream的readObject方法
java反射机制使用java.lang.Class或java.lang.reflect.Constructor的newInstance()方法
调用对象的clone()方法
解释
构造函数的作用是完成对象的初始化。当程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化。而选项B、D中,对象的初始化并不是通过构造函数完成的,而是读取别的内存区域中的对象的各个域来完成。

题目的四个选项是构造方法new,序列化对象,反射,克隆分别创建一个对象的方法,,只有new和反射用到了构造方法
readObject方法只是从文件中还原对象,clone只是一种复制拷贝对象。

28 MVC是一种在web应用中常用的架构,下列说法正确的是(ABC)

A. 模型通常代表应用程序中的数据以及用于操纵数据的业务逻辑;

B. 视图是其对应的模型的可视化呈现,视图 将模型渲染成适合于交互的形式(通常为用户界面元素);

C. 控制器是用户与系统之间的纽带,它接受用户输入,并指示模型和视图基于用户输入执行操作(处理数据、展示数据);

D. MVC模式在web应用中的常见实践是:模型接受来自于用户的GET或POST请求数据并决定如何处理,模型将用户数据转交给控制器,控制器将控制权转交给视图(视图由HTML生成);

E. 以上全不是。
解释
modle相当于dao层,负责和数据库的交互;
view就是视图层,是展现给用户看的;
controller相当于service层,用于承接modle和view之间的数据交互

ABC. D应该是controller接收用户post或者get方式的请求

29 下面哪个Set类是排序的(B)?
LinkedHashSet
TreeSet
HashSet
AbstractSet

TreeSet自然排序,LinkedHashSet按添加顺序排序
LinkedHashSet继承于HashSet、又基于 LinkedHashMap 来实现TreeSet
使用二叉树的原理对新 add()的对象按照指定的顺序排序(升序、降序),每增加一个对象都会进行排序,将对象插入的二叉树指定的位置。
HashSet存储元素的顺序并不是按照存入时的顺序(和 List 显然不同) 而是按照哈希值来存的所以取数据也是按照哈希值取得

30 java基本类型的默认值和取值范围

牛客刷题笔记--(java基础1-50)_第11张图片byte占8位,而且有正有负。最大值当然就是01111111 = 2^7 - 1。因为负的二进制有个按位取反再加1的操作,所以最小值是10000000,按位取反后为11111111,再加1后为110000000 = -2^7
char占16位,而且没有负值。所以最小值是0。最大值是1111111111111111 = 2^16 - 1

31 要导入java/awt/event下面的所有类
java.awt.*是导入java\awt包下所有的类,并不包括其子包下的类。
java.awt.event.*才能导入java\awt\event包下的类。
32下面哪种情况会导致持久区jvm堆内存溢出?©
循环上万次的字符串处理
在一段代码内申请上百M甚至上G的内存
使用CGLib技术直接操作字节码运行,生成大量的动态类
不断创建对象

解释
JVM 堆内存设置原理

java的堆内存分为两块:permantspace(持久带) 和 heap space。
持久带中主要存放用于存放静态类型数据,如 Java Class, Method 等, 与垃圾收集器要收集的Java对象关系不大。
而heapspace分为年轻带和年老带
年轻代的垃圾回收叫 Young GC, 年老代的垃圾回收叫 Full GC。
在年轻代中经历了N次(可配置)垃圾回收后仍然存活的对象,就会被复制到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象
年老代溢出原因有 循环上万次的字符串处理、创建上千万个对象、在一段代码内申请上百M甚至上G的内存,即A B D选项
持久代溢出原因 动态加载了大量Java类而导致溢出

一个对象的一生:我是一个普通的Java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了挺长时间。有一天Eden区中的人实在是太多了,我就被迫去了Survivor区的“From”区,自从去了Survivor区,我就开始漂了,有时候在Survivor的“From”区,有时候在Survivor的“To”区,居无定所。直到我18岁的时候,爸爸说我成人了,该去社会上闯闯了。于是我就去了年老代那边,年老代里,人很多,并且年龄都挺大的,我在这里也认识了很多人。在年老代里,我生活了20年(每次GC加一岁),然后被回收。
VM堆内存分为2块:Permanent Space 和 Heap Space。

Permanent 即 持久代(Permanent Generation),主要存放的是Java类定义信息,与垃圾收集器要收集的Java对象关系不大。
Heap = { Old + NEW = {Eden, from, to} },Old 即 年老代(Old Generation),New 即 年轻代(Young Generation)。年老代和年轻代的划分对垃圾收集影响比较大。 

年轻代

所有新生成的对象首先都是放在年轻代。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。年轻代一般分3个区,1个Eden区,2个Survivor区(from 和 to)。

大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当一个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当另一个Survivor区也满了的时候,从前一个Survivor区复制过来的并且此时还存活的对象,将可能被复制到年老代。

2个Survivor区是对称的,没有先后关系,所以同一个Survivor区中可能同时存在从Eden区复制过来对象,和从另一个Survivor区复制过来的对象;而复制到年老区的只有从另一个Survivor区过来的对象。而且,因为需要交换的原因,Survivor区至少有一个是空的。特殊的情况下,根据程序需要,Survivor区是可以配置为多个的(多于2个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。

针对年轻代的垃圾回收即 Young GC。
年老代

在年轻代中经历了N次(可配置)垃圾回收后仍然存活的对象,就会被复制到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。

针对年老代的垃圾回收即 Full GC。
持久代

用于存放静态类型数据,如 Java Class, Method 等。持久代对垃圾回收没有显著影响。但是有些应用可能动态生成或调用一些Class,例如 Hibernate CGLib 等,在这种时候往往需要设置一个比较大的持久代空间来存放这些运行过程中动态增加的类型。

所以,当一组对象生成时,内存申请过程如下:

JVM会试图为相关Java对象在年轻代的Eden区中初始化一块内存区域。
当Eden区空间足够时,内存申请结束。否则执行下一步。
JVM试图释放在Eden区中所有不活跃的对象(Young GC)。释放后若Eden空间仍然不足以放入新对象,JVM则试图将部分Eden区中活跃对象放入Survivor区。
Survivor区被用来作为Eden区及年老代的中间交换区域。当年老代空间足够时,Survivor区中存活了一定次数的对象会被移到年老代。
当年老代空间不够时,JVM会在年老代进行完全的垃圾回收(Full GC)。
Full GC后,若Survivor区及年老代仍然无法存放从Eden区复制过来的对象,则会导致JVM无法在Eden区为新生成的对象申请内存,即出现“Out of Memory”。

OOM(“Out of Memory”)异常一般主要有如下2种原因:

  1. 年老代溢出,表现为:java.lang.OutOfMemoryError:Javaheapspace
    这是最常见的情况,产生的原因可能是:设置的内存参数Xmx过小或程序的内存泄露及使用不当问题。
    例如循环上万次的字符串处理、创建上千万个对象、在一段代码内申请上百M甚至上G的内存。还有的时候虽然不会报内存溢出,却会使系统不间断的垃圾回收,也无法处理其它请求。这种情况下除了检查程序、打印堆内存等方法排查,还可以借助一些内存分析工具,比如MAT就很不错。

  2. 持久代溢出,表现为:java.lang.OutOfMemoryError:PermGenspace
    通常由于持久代设置过小,动态加载了大量Java类而导致溢出 ,解决办法唯有将参数 -XX:MaxPermSize 调大(一般256m能满足绝大多数应用程序需求)。将部分Java类放到容器共享区(例如Tomcat share lib)去加载的办法也是一个思路,但前提是容器里部署了多个应用,且这些应用有大量的共享类库
    33结构型模式中最体现扩展性的模式是(A)
    装饰模式
    合成模式
    桥接模式
    适配器

解释
链接:https://www.nowcoder.com/questionTerminal/8118573affd743df95045267464089ab

结构型模式是描述如何将类对象结合在一起,形成一个更大的结构,结构模式描述两种不同的东西:类与类的实例。故可以分为类结构模式和对象结构模式。

在GoF设计模式中,结构型模式有:
1.适配器模式 Adapter
适配器模式是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
两个成熟的类需要通信,但是接口不同,由于开闭原则,我们不能去修改这两个类的接口,所以就需要一个适配器来完成衔接过程。
2.桥接模式 Bridge
桥接模式将抽象部分与它的实现部分分离,是它们都可以独立地变化。它很好的支持了开闭原则和组合锯和复用原则。实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这些多角度分离出来让他们独立变化,减少他们之间的耦合。
3.组合模式 Composite
组合模式将对象组合成树形结构以表示部分-整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
4.装饰模式 Decorator
装饰模式动态地给一个对象添加一些额外的职责,就增加功能来说,它比生成子类更灵活。也可以这样说,装饰模式把复杂类中的核心职责和装饰功能区分开了,这样既简化了复杂类,有去除了相关类中重复的装饰逻辑。 装饰模式没有通过继承原有类来扩展功能,但却达到了一样的目的,而且比继承更加灵活,所以可以说装饰模式是继承关系的一种替代方案。

装饰模式的作用就是为了:1.扩展功能2.不用继承

5.外观模式 Facade

外观模式为子系统中的一组接口提供了同意的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

外观模式中,客户对各个具体的子系统是不了解的,所以对这些子系统进行了封装,对外只提供了用户所明白的单一而简单的接口,用户直接使用这个接口就可以完成操作,而不用去理睬具体的过程,而且子系统的变化不会影响到用户,这样就做到了信息隐蔽。
6.享元模式 Flyweight

享元模式为运用共享技术有效的支持大量细粒度的对象。因为它可以通过共享大幅度地减少单个实例的数目,避免了大量非常相似类的开销。.
享元模式是一个类别的多个对象共享这个类别的一个对象,而不是各自再实例化各自的对象。这样就达到了节省内存的目的。
7.模式 Proxy
为其他对象提供一种,并由***对象控制对原对象的引用,以间接控制对原对象的访问。

34 java有8种基本类型,请问byte、int、long、char、float、double、boolean各占多少个字节?

答:1 4 8 2 4 8 1
解释一下boolean占多大的空间,JVM规范给出的是4个字节也就是单个boolean当做int处理,boolean数组1个字节的定义,具体还要看虚拟机实现是否按照规范来,1个字节、4个字节都是有可能的。其实这就是运算效率与存储空间之间的博弈

35子类要调用继承自父类的方法,必须使用super关键字(错误)。

1子类构造函数调用父类构造函数用super
2、子类重写父类方法后,若想调用父类中被重写的方法,用super
3、未被重写的方法可以直接调用。

36下面代码的输出结果是什么?

public class ZeroTest {
    public static void main(String[] args) {
     try{
       int i = 100 / 0;
       System.out.print(i);
  }catch(Exception e){
       System.out.print(1);
       throw new RuntimeException();
  }finally{
       System.out.print(2);
  }
      System.out.print(3);
 }
 }

还是需要理解Try…catch…finally与直接throw的区别:try catch是直接处理,处理完成之后程序继续往下执行,throw则是将异常抛给它的上一级处理,程序便不往下执行了。本题的catch语句块里面,打印完1之后,又抛出了一个RuntimeException,程序并没有处理它,而是直接抛出,因此执行完finally语句块之后,程序终止了

37 以下程序的执行结果是:

static boolean foo(char c)
 {
 System.out.print(c);
 return true;
 }
 public static void main(String[] args) {
 int i =0;
 for(foo('A');foo('B')&&(i<2);foo('C'))
 {
 i++;
 foo('D');
 }
 }
ABDCBDCB

1.其实foo(‘A’);就是初始化条件,只会执行一次,所以第一个打印的肯定是A
2.因为i=0;循环条件是i<2 (由此可知循环i等于2的时候就会停止循环,)所有0<2满足条件,接着会输出B,然后执行i++;i就变成1了,再输出D,再最后输出C,一次循环后的结果是:ABDC
3.第二次循环的开始是foo(‘A’);是初始条件所以不会执行,直接从foo(‘B’)开始,输出B,然后i为1,且小于2,此时循环体内再次执行i++;i的值为2了,再次输出D,最后输出C
第二次循环输出:BDC
4.*然后循环再次执行for(foo(‘A’);foo(‘B’)&&(i<2);foo(‘C’))
直接输出B,***i的值在第二轮循环后的值变成了2,2<2不成立,终止循环,输出B

考察的是for循环三条语句的执行顺序 for(第一条语句;第二条语句;第三条语句;) 首次循环时先执行前两句。以后的每次循环结束,都是执行最后一条语句,然后执行判断语句(也就是第二条语句)条件成立进入下一次循环。 第一条语句只会被执行一次

for(循环开始条件;判断条件;循环后条件)按照执行顺序依次执行

38 synchronized关键字和volatile关键字比较

volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。
多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞
volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。
volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。

synchronized: 具有原子性,有序性和可见性;(三个都有)
volatile:具有有序性和可见性(缺一个原子性)

synchronized关键字和volatile关键字的不同点:
* 粒度不同,volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。
* 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞。
* volatile只能保证可见性和有序性不能保证原子性,而synchronized则三者都能保证
* volatile关键字主要用于解决变量在多个线程之间的可见性,而synchronized解决的则是多个线程之间访问资源的同步性
更具体的可参考网址:java面试题之volatile和synchronized的使用方法和区别

39 下列Java代码中的变量a、b、c分别在内存的____存储区存放。

class A {
    private String a = “aa”;
    public boolean methodB() {
        String b = “bb”;
        final String c = “cc”;
    }
}
堆区、栈区、栈区

解释
a是类中的成员变量,存放在堆区
b、c都是方法中的局部变量,存放在栈区

堆区:只存放类对象,线程共享;
方法区:又叫静态存储区,存放class文件和静态数据,线程共享;
栈区:存放方法局部变量,基本类型变量区、执行环境上下文、操作指令区,线程不共享;

牛客刷题笔记--(java基础1-50)_第12张图片40 以下关于继承的叙述正确的是(A)
在Java中类只允许单一继承
在Java中一个类不能同时继承一个类和实现一个接口
在Java中接口只允许单一继承
在Java中一个类只能实现一个接口

解释
类支持单继承,接口支持多继承

接口可以继承接口,而且可以继承多个接口,但是不能实现接口,因为接口中的方法全部是抽象的,无法实现;
另外,如果是Java 7以及以前的版本,那么接口中可以包含的内容有:1. 常量;2. 抽象方法
如果是Java 8,还可以额外包含有:3. 默认方法;4. 静态方法
如果是Java 9,还可以额外包含有:5. 私有方法
2)普通类可以实现接口,并且可以实现多个接口,但是只能继承一个类,这个类可以是抽象类也可以是普通类,如果继承抽象类,必须实现抽象类中的所有抽象方法,否则这个普通类必须设置为抽象类;

3)抽象类可以实现接口,可以继承具体类,可以继承抽象类,也可以继承有构造器的实体类。
抽象类中可以有静态main方法;抽象类里可以没有抽象方法,没有抽象方法的抽象类就是不想让别人实例化它;
另外,抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已。在继承了抽象类的子类中通过super(参数列表)调用抽象类中的构造方法,可以用于实例化抽象类的字段。

下面总结常见的抽象类与接口的区别:
1)抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象;
2)接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现(java8中 接口可以有实现方法 使用default修饰);
3)接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量;
4)抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个类实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类;
5)抽象方法要被实现,所以不能是静态static的,也不能是私有private的,也不能被final修饰(试想一下,静态方法可以被类名直接调用,而类名直接调用一个没有实现的抽象方法没有意义)。

41 有关线程的叙述正确的是©
可以获得对任何对象的互斥锁定。
通过继承Thread类或实现Runnable接口,可以获得对类中方法的互斥锁定。
线程通过使用synchronized关键字可获得对象的互斥锁定。
线程的创建只能通过继承Thread类来实现。
解释
采用synchronized修饰符实现的同步机制叫做互斥锁机制,它所获得的锁叫做互斥锁。每个对象都有一个monitor(锁标记),当线程拥有这个锁标记时才能访问这个资源,没有锁标记便进入锁池。任何一个对象系统都会为其创建一个互斥锁,这个锁是为了分配给线程的,防止打断原子操作。每个对象的锁只能分配给一个线程,因此叫做互斥锁。
互斥锁指的是只有一个线程可以访问该对象。
通过继承Thread类或实现Runnable接口,只是创建线程的两种方式。
如果变量用volatile修饰,则该变量是线程共享的,无法获得该变量的互斥锁

42 在java中,已定义两个接口B和C,要定义一个实现这两个接口的类,以下语句正确的是()
答:class A implements B,C
类实现多个接口的时候,只需要一个implements,多个接口通过逗号进行隔开,先继承类再实现接口

43 以下不是修饰符final的作用的是(C )。
修饰常量
修饰不可被继承的类
修饰不可变类
修饰不可覆盖的方法

final的作用:
1. 修饰变量,变量的引用地址不可变,但是地址中的内容可以变。
2. 修饰方法,方法不可被重写,但是还是可以重载
3. 修饰类,类不可继承。

不可变类,说的是一个类一旦被实例化,就不可改变自身的状态。常见的比如String和基本数据类型的包装类,对于这种不可变类,一旦在进行引用传递的时候,形参一开始就和实际参数指向的不是一个地址,所以在方法中对形参的改变,并不会影响实际参数。

不可变类(Immutable Class)是一旦被实例化就不会改变自身状态(或值)的类。
String就是一种典型的不可变类。
不可变类的主要用途是在多线程环境下确保对象的线程安全。
不可变类一般建议使用final来修饰(比如String就是final类),否则子类可以通过继承不可变类的方式,增加setter方法,从而改变对象的状态,破坏了不可变的约束。

44 下列说法正确的是(B)
在类方法中可用this来调用本类的类方法
在类方法中调用本类的类方法可直接调用
在类方法中只能调用本类的类方法
在类方法中绝对不能调用实例方法
A this指当前对象只能在实际方法和构造函数中调用。C 可以调用其他类的非私有类方法。D 不能直接调用,要先生成对象。通过对象即可调用实例方法。

45 如下代码,执行test()函数后,屏幕打印结果为()

public class Test2
{
    public void add(Byte b)
    {
        b = b++;
    }
    public void test()
    {
        Byte a = 127;
        Byte b = 127;
        add(++a);
        System.out.print(a + " ");
        add(b);
        System.out.print(b + "");
    }
}


包装类的值都是final 不可变的,对于++b 或者b++ ,只是新创建了一个对象,然后把引用传给了原对象句柄,在函数中操作,只是形参的临时句柄改变了指向,实参的句柄还是指向原来的对象。所以即使不是b = b++ 这种,b的值在add之后也是不会变的。
该题的详细分析可参见博客:http://www.cnblogs.com/nailperry/p/4780354.html
这里简单说明两点:
1.b = b++;这一操作并未改变b的值,原因详见http://blog.csdn.net/lm2302293/article/details/6713147;
2.++a先是触发拆箱操作Byte.byteValue,得到基本类型的值127,然后执行+1操作,使得值变为-128,最后触发装箱操作Byte.valueOf将value=-128的Byte对象赋值给a。

46 下列方法中哪个是线程执行的方法? (A)
run()
start()
sleep()
suspend()

run()方法用来执行线程体中具体的内容
start()方法用来启动线程对象,使其进入就绪状态
sleep()方法用来使线程进入睡眠状态
suspend()方法用来使线程挂起,要通过resume()方法使其重新启动

47 以下各类中哪几个是线程安全的?( BCD)
ArrayList
Vector
Hashtable
Stack

线程同步:喂,SHE
喂(Vector)
S(Stack)
H(hashtable)
E(enumeration)
牛客刷题笔记--(java基础1-50)_第13张图片
48 character流和byte流的区别不包括(ABD)
每次读入的字节数不同
前者带有缓冲,后者没有。
前者是字符读入,后者是字节读入。
二者没有区别,可以互换。

字符流和字节流每次读入的字节数是不确定的,可能相同也可能不相同;字符流和字节流都有缓冲流
Java的流操作分为字节流和字符流两种。
字节流与字符流主要的区别是他们的处理方式
字节流是最基本的,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的。但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化
这两个之间通过 InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联。

在实际开发中出现的汉字问题实际上都是在字符流和字节流之间转化不统一而造成的。
字节流---->字符流
字节流转化为字符流,实际上就是byte[]转化为String时,
public String(byte bytes[], String charsetName)
有一个关键的参数字符集编码,通常我们都省略了,那系统就用操作系统的lang
字符流---->字节流

字符流转化为字节流,实际上是String转化为byte[]时,byte[] String.getBytes(String charsetName)也是一样的道理至于java.io中还出现了许多其他的流,按主要是为了提高性能和使用方便,如BufferedInputStream,PipedInputStream等

常识:

对于GBK编码标准,英文占用1个字节,中文占用2个字节
对于UTF-8编码标准,英文占用1个字节,中文占用3个字节
对于Unicode编码标准,英文中文都是2个字节。这也是为什么叫做unicode

字符流和字节流每次读入的字节数是不确定的,可能相同也可能不相同
例FileInputStream 的read() 方法每次读入一个字节,read(byte b[]) 每次读入b.length个字节
FileReader 的read()方法每次读入一个字符,read(char cbuf[], int offset, int length)每次读入length个字符
另外,字符流和字节流读入一个ASCII字符,字节数是相同的
例UTF-8字符编码中一个汉字占三个字节,数字1占一个字节,用字符流读入的数字1长度为一个字节,用字节流读入的数字1长度也为一个字节

49 基本数据类型均可任意互相转换(错误)。

原生类是指Java中,数据类型分为基本数据类型(或叫做原生类、内置类型)和引用数据类型。
那么原生类为基本数据类型,有八种,这样转换的时候就有表达范围问题。
1、所占位数少的可以转换为所占位数多的类型,比如byte转char,char转int等;
2、而所占位数多的转为所占位数少的默认情况下不能实现转换,需要强制类型转换,这样可能会丢失一部分原始数据;
3、此外,boolean类型数据和其他七种不能互相转换。

final修饰的变量内容是不能修改的,如果final修饰一个对象的引用,那么指的是这个对象的地址值是无法改变的,对象的内容还是可以修改的。如果final修饰一个普通变量的话,就是变量的值无法修改。综上,final修饰变量的本质就是:修饰的变量值(地址或内容)无法改变。

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

非纯数字的字符串转化为Integer对象会报数字格式异常。

50 定义:String s1 = “uml”; String s2 = “uml”; String s3= new String(“uml”); String s4= new String(“uml”);那么,s1==s2;s3 == s4;s1.equals(s3); 判断正确与否

T,F,T

解释

:比较两个引用的地址和值
equals:比较两个引用的值
1、s1
s2 true s1和s2指向字符串常量池中同一个地址
2、s3 和 s4 都显示使用了new,是不同的对象, 当然不相等
3、s1 和 s3 的值都是 “uml”,当然相等
牛客刷题笔记--(java基础1-50)_第14张图片

通常情况下,equals方法(Object)和==在比较抽象数据类型时没区别,均为比较地址值。String中的equals方法是重写过的,作用比较对象中的内容是否相同。

你可能感兴趣的:(Java)