1、Spring DAO 中最常用的类是()
A,JdbcTemplate ,SimpleJdbcTemplate
B,SimpleJdbcInsert,SimpleJdbcProcedure
C,SimpleJdbcInsert ,SimpleJdbcStoredProc
D,SimpleJdbcQuery ,SimpleJdbcExec
正确答案:A
2、Spring AOP 中, 织入(Weaving) 可以在下面什么时间完成()
A,全部选项
B,Run time
C,Load time
D,Compile time
正确答案:A
3、下面关于Spring MVC 描述正确的是()
A,DispatcherServlet在 Spring MVC 中是核心servlet , 它负责接收请求并将请求分发给适合的控制器
B,在Spring MVC 中,可以配置多个DispatcherServlet
C,全部选项
D,要使Spring MVC可用,DispatcherServlet需要在web.xml中配置
正确答案:C
4、下面哪项是Spring自动装载模式()
A,autodetect
B,全部选项
C,constructor
D,byname, byType
正确答案:B
5、Spring 中,下面哪一项不是使用事务的方法()
A,proxies
B,declaratively
C,programmaticly
正确答案:A
6、Spring提供了JMS层的抽象,正确吗()
A,正确
B,错误
正确答案:A
7、关于"@Order"注解,最正确的描述是()
A,实现org.springframework.core.Ordered接口
B,指定一个bean的范围
C,通常用于注入域对象的属性
D,全不正确
正确答案:A
8、如何在Spring应用中使用SLF4J()
A,作为日志框架
B,全不正确
C,作为一个bean
D,作为JDBC框架
正确答案:A
9、Spring bean 的默认作用范围是()
A,全不正确
B,Singleton
C,Prototype
D,Session
E, Abstract
正确答案:B
10、Spring中,单例意味着每_____只有一个实例()
A,Context
B, JVM
C,Thread
正确答案:A
21、使用Spring MVC 处理普通页面请求, 下面哪个排序是正确的()
1.请求:请求提交给服务器
2.分发:分发器通过web 应用配置信息 , 将请求分发至适当的控制器
3.服务调用:控制器与业务层交互
4.响应:控制器更新模型,将执行结果返回给客户端展现
A,1-2-3-4
B,1-4-3-2
C,1-4-2-3
D,1-3-2-4
正确答案:A
22、以下哪个不是 Spring AOP 的注解()
A,@Before
B,@Around
C,@BeforeReturning
D,@AfterThrowing
正确答案:C
23、"@RequestMapping是Spring中的哪一部分()
A,DAO
B,Security
C,Web MVC
D,Web
正确答案:C
24、下面关于spring和struts2的描述,错误的是()
A,spring mvc的入口是filter,而struts2是servlet
B,spring mvc是基于方法的设计,而struts2是基于类的设计
C,struts2有以自己的interceptor机制,spring mvc用的是独立的AOP方式
D, spring mvc的方法之间基本上独立的,独享request response数据,struts2所有Action变量是共享的
正确答案:A
25、Spring中,下面哪个选项支持ORM()
A,OJB
B,TopLink
C,全部选项
D,Java Data Objects(JDO)
E,iBatis
正确答案:C
26、Spring和Hibernate的集成中,下面哪项是SessionFactory 正确的实现()
A,LocalSessionFactoryBean
B,LocalFactoryBean
C,SessionFactory
D,SessionFactoryBean
正确答案:A
27、下面哪个是Spring最核心的servlet()
A,WebServlet
B,SpringServlet
C,DispatcherServlet
D,IoCServlet
正确答案:C
28、Spring-test 用什么约定在测试中使用HTTP会话和HTTP 请求对象()
A,MVC
B,Open-closed principle
C,DAOs
D,Mock objects
正确答案:D
29、Spring 中,"@Cacheable"的key生成方式,以下哪个是正确的()
A,可以是方法参数及其成员变量的任意表达式
B,只能使用所有方法参数,但可以调整次序
C,只能使用所有方法参数,且不能调整次序
D,只能指定方法参数是否参与key的生成,不能控制参数的成员变量
正确答案:A
30、使用@Required但不关联bean 来注解setter方法,将会发生()
A,bean被设置为null
B,启动异常
C,Spring 将创建bean
D,什么也不发生
正确答案:B
1,有关线程的哪些叙述是对的( )
A,一旦一个线程被创建,它就立即开始运行。
B,使用start()方法可以使一个线程成为可运行的,但是它不一定立即开始运行。
C,当一个线程因为抢先机制而停止运行,它被放在可运行队列的前面。
D,一个线程可能因为不同的原因停止并进入就绪状态。
答案:BCD
在抢占式线程模型中,操作系统可以在任何时候打断线程。通常会在它运行了一段时间(就是所谓的一个时间片)后才打断它。这样的结果自然是没有线程能够不公平地长时间霸占处理器。
2,哪个关键字可以对对象加互斥锁 ()
A,serialize
B,synchronized
C,transient
D,static
答案:B
A是对象串行化、C是关键字transient修饰的属性将不被串行化、D是静态的
3,下列关于线程优先级的说法中,正确的是()
A、线程的优先级是不能改变的
B、线程的优先级是在创建线程时设置的
C、在创建线程后的任何时候都可以设置
D、B和C
答案:C
Java语言中线程的优先级是用一个介于MIN_PRIORITY和MAX_PRIORITY之间的整数来表示的。可以在创建线程后的任何时候修改线程的优先级。
4,为了使模块尽可能独立,要求( )
A.模块的内聚程度要尽量高,且耦合程度要尽量强
B.模块的内聚程度要尽量高,且耦合程度要尽量弱
C.模块的内聚程度要尽量低,且耦合程度要尽量弱
D.模块的内聚程度要尽量低,且耦合程度要尽量强
答案:B
系统设计的质量主要反映在模块的独立性上。评价模块独立性的主要标准有两个:一是模块之间的耦合,它表明两个模块之间互相独立的程度;二是模块内部之间的关系是否紧密,称为内聚。一般来说,要求模块之间的耦合尽可能地弱,即模块尽可能独立,而要求模块的内聚程度尽量高。
5,下列对于线性链表的描述中正确的是()
A.存储空间不一定是连续,且各元素的存储顺序是任意的
B.存储空间不一定是连续,且前件元素一定存储在后件元素的前面
C.存储空间必须连续,且前件元素一定存储在后件元素的前面
D.存储空间必须连续,且各元素的存储顺序是任意的
答案:A
在链式存储结构中,存储数据结构的存储空间可以不连续,各数据结点的存储顺序与数据元素之间 的逻辑关系可以不一致,而数据元素之间的逻辑关系是由指针域来确定的。
6,下列叙述中错误的是( )
A.线性表是由n个元素组成的一个有限序列
B.线性表是一种线性结构
C.线性表的所有结点有且仅有一个前件和后件
D.线性表可以是空表
答案:C
线性表是一种线性结构,由n(n≥0)个元素组成,所以线性表可以是空表。但是在线性表中,第一个结点没有前驱,最后一个结点没有后继,其他结点有且只有一个前驱和后继,所以选项C是错误的。
7,已知一棵二叉树前序遍历和中序遍历分别为ABDEGCFH和DBGEACHF,则该二叉树的后序遍历为( )
A.GEDHFBCA
B.DGEBHFCA
C.ABCDEFGH
D.ACBFEDHG
答案:B
二叉树的遍历有3种:前序、中序和后序。
先序:先访问根结点、左结点、右结点
中序:先访问左结点、根结点、右结点
后序:先访问左结点、右结点、根结点
本题根据前序遍历和中序遍历的结果可以得出二叉树的结构,然后再对其进行后序遍历。
8,面向对象方法中,继承是指( )
A.一组对象所具有的相似性质
B.一个对象具有另一个对象的性质
C.各对象之间的共同性质
D.类之间共享属性和操作的机制
答案:D
继承:在程序设计中,继承是指子类自动享用父类的属性和方法,并可以增加新的属性和方法的一种机制。它是实现代码共享的重要手段,可以使软件更具有开放性、可扩充性,这是信息组织与分类的行之有效的方法,也是面向对象的主要优点之一。
继承又分为单重继承和多重继承,单重继承是指子类只能继承一个父类的属性和操作;而多重继承是指子类可以继承了多个父类的属性和操作。
扩展:Java是一种单重继承语言,而C++是一种多重继承语言。
9,栈和队列的共同点是( )
A.都是先进先出
B.都是先进后出
C.只允许在端点处插入和删除元素
D.没有共同特点
答案:C
栈是只允许在表的一端进行插入和删除的操作,队列是允许在表的一端进行插入,另一端进行删除的操作。
10,下列关于修饰符混用的说法,错误的是()
A.abstract不能与final并列修饰同一个类
B.abstract类中不可以有private的成员
C.abstract方法必须在abstract类中
D.static方法中能处理非static的数据
答案:D
静态方法是属于类的,而普通方法是属于对象的。
属于类的静态方法可以在对象不存在的时候就能访问到,而普通方法必须先new一个对象才能用这个对象访问。当我们访问调用静态方法的时候(使用类名.静态方法名)这个时候就没有对象创建,所以普通方法是访问不到的。为了避免这种错误,所以java就不允许在静态方法中访问非静态方法。
1,volatile关键字是否能保证线程安全?()
答案:否
volatile关键字用在多线程同步中,可保证读取的可见性,JVM只是保证从主内存加载到线程工作内存的值是最新的读取值,而非cache中。但多个线程对volatile的写操作,无法保证线程安全。
假如线程1,线程2 在进行read,load 操作中,发现主内存中count的值都是5,那么都会加载这个最新的值,在线程1对count进行修改之后,会write到主内存中,主内存中的count变量就会变为6;线程2由于已经进行read,load操作,在进行运算之后,也会更新主内存count的变量值为6;导致两个线程及时volatile关键字修改之后,还是会存在并发的情况。
2,下面哪个流类属于面向字符的输入流( )
A、BufferedWriter
B、FileInputStream
C、ObjectInputStream
D、InputStreamReader
答案:D
Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式。
面向字节的操作为以8位为单位对二进制的数据进行操作,对数据不进行转换,这些类都是InputStream和OutputStream的子类。
面向字符的操作为以字符为单位对数据进行操作,在读的时候将二进制数据转为字符,在写的时候将字符转为二进制数据,这些类都是Reader和Writer的子类。
3,Java能不能不通过构造函数创建对象()
A、能 B、不能
答案:A
Java创建对象的几种方式:
(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。
4,下列哪个叙述是正确的()
A.子类继承父类的构造方法。
B.abstract类的子类必须是非abstract类。
C.子类继承的方法只能操作子类继承和隐藏的成员变量。
D.子类重写或新增的方法也能直接操作被子类隐藏的成员变量。
答案:C
子类是不继承父类的构造方法的,而是必须调用其父类的构造方法。
abstract类的子类可以是abstract类,如果是非abstract类,就必须重写父类中所有的abstract方法。
D中子类新增的方法是不能直接操作被子类隐藏的成员变量的。
5,下列哪个叙述是正确的()
A.final类可以有子类。
B.abstract类中只可以有abstract方法。
C.abstract类中可以有非abstract方法,但该方法不可以用final修饰。
D.不可以同时用final和abstract修饰同一个方法。
E.允许使用static修饰abstract方法。
答案:D
用final修饰的类是不允许被继承的,A错误
abstract类中也可以有普通成员方法,B错误
abstract类中的非abstract方法是可以用final修饰的,而abstract方法是不可以被final修饰的,C错误
D同上,正确
不允许使用static修饰abstract方法,E错误。
6,当检索一个压缩文件时,首先要建立压缩文件输入流对象,该对象()
A、以选中的压缩文件为参数
B、以FileInputStream对象为参数
C、以InputStreamReader对象为参数
D、以BufferedReader对象为参数
答案:B
在java.io包中提供了对压缩文件进行操作的能力。它是通过压缩文件输入流与压缩文件输出流来实现的,其分别继承自InflaterInputStream与DeflaterOutputStream。
在创建压缩文件输入流时,其初始化参数是一个FileInputStream类的实例。
7,已知一个有序线性表为()(13,18,24,35,47,50,62,83,90,115,134),当用二分法查找值为90的元素时,查找成功的比较次数为( )
A,1 B,2 C,3 D,9
答案:B
根据二分法查找需要两次:首先将90与表中间的元素50进行比较,由于90大于50,所以在线性表的后半部分查找;第二次比较的元素是后半部分的中间元素,即90,这时两者相等,即查找成功。
8,Java程序的并发机制是( )
A.多线程
B.多接口
C.多平台
D.多态性
答案:A
Java是通过多线程实现并发机制的。多线程是指一个程序中包含多个执行流, 多线程程序设计的含义是可以将程序任务分成几个并行的子任务。
9,下列选项中,不属于模块间耦合的是( )
A.数据耦合
B.标记耦合
C.异构耦合
D.公共耦合
答案:C
模块之间的耦合程度反映了模块的独立性,也反映了系统分解后的复杂程度。 按照耦合程度从弱到强,可以将其分成7级。
分别是非直接耦合、数据耦合、标记耦合、控制 耦合、外部耦合、公共耦合和内容耦合。其中没有异构耦合这种方式。
10,下列关于内部类的说法不正确的是 ( )
A,内部类的类名只能在定义它的类或程序段中或在表达式内部匿名使用
B,内部类可以使用它所在类的静态成员变量和实例成员变量
C,内部类不可以用abstract修饰符定义为抽象类
D,内部类可作为其他类的成员,而且可访问它所在类的成员
答案:C
内部类不仅可以用abstract修饰定义为抽象类,也可以用private或protected定义,所以选项C说法错误。
1,下列说法正确的是()
A.一个文件里可以同时存在两个public修饰的类
B.构造函数可以被重写(override)
C.子类不能访问父类非public和protected修饰的属性
D.final修饰的类可以被继承
答案:C
一个Java源文件中最多只能有一个public类,当有一个public类时,源文件名必须与之一致,否则无法编译,如果源文件中没有一个public类,则文件名与类中没有一致性要求。至于main()不是必须要放在public类中才能运行程序。
重写是子类继承父类后对父类的方法进行修改。方法名,参数,返回值必须一样。 不能重写被标示为final的方法。如果不能继承一个方法,则不能重写这个方法。
扩展:重写override,重载overload的区别
java的方法重载
就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法,而且返回值类型可以相同也可以不相同,这也是面向对象的多态性。
java的方法重写
父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
子类函数的访问修饰权限不能少于父类的;
重写方法只能存在于具有继承关系中,重写方法只能重写父类非私有的方法。
2,for(int x=0,y=0;(y!=0)&&(x<4);x++)循环的执行次数是()
A.无限次
B.执行4次
C.执行3次
D.一次也不执行
答案:D
y初始值为0,在整个for循环中,y的值不变,故判断语句中的(y!=0)不成立,故一次也不执行。
3,关于 JAVA 堆,下面说法错误的是( )
A.所有类的实例和数组都是在堆上分配内存的
B.对象所占的堆内存是由自动内存管理系统回收
C.堆内存由存活和死亡的对象,空闲碎片区组成
D.数组是分配在栈中的
答案:D
首先数组是分配在堆中的,故D的说法不正确。
Java堆的结构:JVM的堆是运行时数据区,所有类的实例和数组都是在堆上分配内存。它在JVM启动的时候被创建。对象所占的堆内存是由自动内存管理系统也就是垃圾收集器回收。堆内存是由存活和死亡的对象组成的。存活的对象是应用可以访问的,不会被垃圾回收。死亡的对象是应用不可访问尚且还没有被垃圾收集器回收掉的对象。一直到垃圾收集器把这些对象回收掉之前,他们会一直占据堆内存空间。
4,在使用super 和this关键字时,以下描述正确的是()
A.在子类构造方法中使用super()显示调用父类的构造方法;
super()必须写在子类构造方法的第一行,否则编译不通过
B.super()和this()不一定要放在构造方法内第一行
C.this()和super()可以同时出现在一个构造函数中
D.this()和super()可以在static环境中使用,包括static方法和static语句块
答案:A
Java关键字this只能用于方法方法体内。当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是this。因此,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this。
super关键和this作用类似,是被屏蔽的成员变量或者成员方法或变为可见,或者说用来引用被屏蔽的成员变量和成员成员方法。
不过super是用在子类中,目的是访问直接父类中被屏蔽的成员,注意是直接父类(就是类之上最近的超类)
5,下列语句哪一个正确()
A.Java程序经编译后会产生machine code
B.Java程序经编译后会产生byte code
C.Java程序经编译后会产生DLL
D.以上都不正确
答案:B
Java字节码是Java源文件编译产生的中间文件
java虚拟机是可运行java字节码的假想计算机 java的跨平台性也是相对与其他编程语言而言的 。
先介绍一下c语言的编译过程:c的文件经过C编译程序编译后生成windows可执行文件exe文件然后在windows中执行。
再介绍java的编译过程:java的文件由java编译程序将java字节码文件就是class文件在java虚拟机中执行。机器码是由CPU来执行的;Java编译后是字节码。
电脑只能运行机器码。Java在运行的时候把字节码变成机器码。C/C++在编译的时候直接编译成机器码
6,下列哪一种叙述是正确的()
A.abstract修饰符可修饰字段、方法和类
B.抽象方法的body部分必须用一对大括号{ }包住
C.声明抽象方法,大括号可有可无
D.声明抽象方法不可写出大括号
答案:D
abstract修饰符用来修饰类和成员方法
用abstract修饰的类表示抽象类,抽象类位于继承树的抽象层,抽象类不能被实例化。
用abstract修饰的方法表示抽象方法,抽象方法没有方法体。抽象方法用来描述系统具有什么功能,但不提供具体的实现。
Abstract是Java中的一个重要关键字,可以用来修饰一个类或者一个方法。
修饰一个方法时,表示该方法只有特征签名(signature),没有具体实现,而是把具体实现留给继承该类的子类,所以不能有大括号。
7,下列说法正确的有()
A.class中的constructor不可省略
B.constructor必须与class同名,但方法不能与class同名
C.constructor在一个对象被new时执行
D.一个class只能定义一个constructor
答案:C
这里可能会有误区,其实普通的类方法是可以和类名同名的,和构造方法唯一的区分就是,构造方法没有返回值。
8,GC线程是否为守护线程()
答案:是
线程分为守护线程和非守护线程(即用户线程)。
只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。
守护线程最典型的应用就是 GC (垃圾回收器)
9,关于sleep()和wait(),以下描述错误的一项是( )
A. sleep是线程类(Thread)的方法,wait是Object类的方法;
B. sleep不释放对象锁,wait放弃对象锁;
C. sleep暂停线程、但监控状态仍然保持,结束后会自动恢复;
D. wait后进入等待锁定池,只有针对此对象发出notify方法后获得对象锁进入运行状态。
答案:D
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
10,方法resume()负责恢复哪些线程的执行( )
A,通过调用stop()方法而停止的线程。
B,通过调用sleep()方法而停止的线程。
C,通过调用wait()方法而停止的线程。
D,通过调用suspend()方法而停止的线程。
答案:D
suspend可以挂起一个线程,就是把这个线程暂停了,它占着资源,但不运行,用resume是恢复挂起的线程,让这个线程继续执行下去。
1,关于Spring MVC的核心控制器DispatcherServlet的作用,以下说法错误的是( )
A,它负责接收HTTP请求
B,加载配置文件
C,实现业务操作
D,初始化上下应用对象ApplicationContext
正确答案:C
SpringMVC是Spring中的模块,它实现了mvc设计模式,首先用户发起请求,请求到达SpringMVC的前端控制器(DispatcherServlet),前端控制器根据用户的url请求处理器映射器查找匹配该url的handle,并返回一个执行链,前端控制器再请求处理器适配器调用相应的handle进行处理并返回给前端控制器一个modelAndView,前端控制器再请求视图解析器对返回的逻辑视图进行解析,最后前端控制器将返回的视图进行渲染,并把数据装入到request域,返回给用户。
DispatcherServlet作为SpringMVC的前端控制器,负责接收用户的请求,并根据用户的请求返回相应的视图给用户。实现业务在service层,所以c答案错误。
2,下面有关spring的依赖注入,说法错误的是()
A,依赖注入通常有如下两种:设值注入和构造注入:
B,构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入
C,当设值注入与构造注入同时存在时,先执行构造注入,再执行设值注入
D,设值注入是指IoC容器使用属性的setter方法来注入被依赖的实例。这种注入方式比较简单、直观
正确答案:C
使用构造函数依赖注入时,Spring保证一个对象所有依赖的对象先实例化后,才实例化这个对象。使用set方法依赖注入时,Spring首先实例化对象,然后才实例化所有依赖的对象。
当设值注入与构造注入同时存在时,先执行设值注入,再执行构造注入。
3,将元数据配置到Spring容器,下面哪个方法是不正确的()
A,通过编组与解组对象
B,注解基础配置
C,Java基础配置
D,XML基础配置
正确答案:A
有三种方式向Spring 容器提供元数据:1,XML配置文件;2,基于注解配置;3,基于Java的配置,死概念记住即可。
4,下面哪个不是Spring 的注解()
A,@Aspect
B,@Service
C,@Component
D,@Controller
E,@View
正确答案:E
考察对spring的熟悉程度,除E选项之外都是较常用注解。
5,下面有关SPRING的事务传播特性,说法错误的是()
A,PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行
B,PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就抛出异常
C,PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起
D,PROPAGATION_NESTED:支持当前事务,新增Savepoint点,与当前事务同步提交或回滚
正确答案:B
事务的传播属性介绍:
PROPAGATION_REQUIRED --支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS --支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW --新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED --以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER --以非事务方式执行,如果当前存在事务,则抛出异常。
6,下列关于Spring特性中IoC描述错误的是()
A,IoC就是指程序之间的关系由程序代码直接操控
B,所谓“控制反转”是指控制权由应用代码转到外部容器,即控制权的转移
C,IoC将控制创建的职责搬进了框架中,从应用代码脱离开来
D,使用Spring的IoC容器时只需指出组件需要的对象,在运行时Spring的IoC容器会根据XML配置数据提供给它
正确答案:A
IOC,即控制反转(Inversion of Control,英文缩写为IoC),是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。
见如下代码:
public class IntTest {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 150;
Integer i4 = 150;
System.out.println(i1 == i2);
System.out.println(i3 == i4);
}
}
问题来了:输出的结果是什么?
问题分析:
1,首先要搞清楚==与equal的区别以及各自比较的是什么
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。
所以首先弄清楚了,对于上面代码中,我们是比较变量所对应的内存中所存储的数值是否相同。
2,要了解自动装箱和拆箱的概念
JVM会自动维护八种基本数据类型的常量池。
在上面代码中,第一次Integer i1 = 100;时会把i1写入常量池,当定义i2时,数据一样,不会再去创建新的对象,所以,第一个输出的是true。
但是这里Integer并不是八种基本数据类型啊,这里涉及了自动装箱和拆箱的概念。自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。
因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱。原始类型byte,short,char,int,long,float,double和boolean对应的封装类为Byte,Short,Character,Integer,Long,Float,Double,Boolean。
3,int在常量池中的初始化范围
int常量池中初始化-128~127的范围,所以当为Integer i1,i2=100时,在自动装箱过程中是取自常量池中的数值,而当Integer i3,i4=150时,150不在常量池范围内,所以在自动装箱过程中需new 一个150,所以上面代码第二个输出的是false。
下面贴出int常量池的部分代码供大家参考:
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
正确答案:
true
false
下面哪个流类属于面向字符的输入流( )
A BufferedWriter
B FileInputStream
C ObjectInputStream
D InputStreamReader
正确答案:D
以InputStream(输入)/OutputStream(输出)为后缀的是字节流。
以Reader(输入)/Writer(输出)为后缀的是字符流。
给大家一张很nice的图片:
(来自百度图库)
1、下列关于构造方法的叙述中,错误的是()
A、Java语言规定构造方法名与类名必须相同
B、Java语言规定构造方法没有返回值,但不用void声明
C、Java语言规定构造方法不可以重载
D、Java语言规定构造方法通常通过new自动调用
正确答案:C
扩展:
构造方法:用于完成对象属性的初始化工作,有如下特点:
(1)构造方法的名字必须和类名完全一样(包括大小写);
(2)构造方法没有返回值,连void也不会出现;
(3)如果认为没有给类创建一个构造方法,java编译器会自动给我们添加一个没有参数且方法体为空的构造方法。当然,如果已经人为的添加了一个构造方法,java编译器就不会给添加这个构造方法了。
(4)我们不能显式调用类的构造方法,构造方法通常只是通过new关键字隐式调用;
2、以下关于final的描述中,错误的是()
A、final可以用来修饰接口以及抽象类
B、final修饰的变量不允许被再次赋值
C、final修饰的类无法被继承
D、final修饰的变量需要初始化
正确答案:A
扩展:
final不能修饰抽象类和接口。很明显,C选项说了final修饰的类无法被继承,修饰抽象类和接口毫无意义。
final关键字可以用来修饰类、方法、变量、参数。
一,修饰类
1、该类不能被继承。
2、类中的方法不会被覆盖,因此默认都是final的。
二,修饰方法
1、该方法可以被继承,但是不能被覆盖。
2、好处:可以防止继承它的子类修改该方法的意义和实现;更为高效,编译器在遇到调用fianal方法转入内嵌机制,提高了执行效率。
3、注意:父类中的private成员方法不能被子类覆盖,因此,private方法默认是final型的。
三,修饰变量
1、用final修饰后变为常量。包括静态变量、实例变量和局部变量这三种。
2、特点:可以先声明,不给初值,这种叫做final空白。但是使用前必须被初始化。一旦被赋值,将不能再被改变。
四,修饰参数
1、用final修饰参数时,可以读取该参数,但是不能对其作出修改
3、以下关于被private修饰的成员变量的说法正确的是()
A、只能被同一个包中的类访问
B、只能被该类自身所访问和修改
C、可以被两种类访问和引用:该类本身、该类的所有子类
D、可以被三种类所引用:该类自身、与它在同一个包中的其他类、在其他包中的该类的子类
正确答案:B
扩展:
public:
具有最大的访问权限,可以访问任何一个在classpath下的类、接口、异常等。它往往用于对外的情况,也就是对象或类对外的一种接口的形式。
protected:
主要的作用就是用来保护子类的。它的含义在于子类可以用它修饰的成员,其他的不可以,它相当于传递给子类的一种继承的东西
default:
有时候也称为friendly,它是针对本包访问而设计的,任何处于本包下的类、接口、异常等,都可以相互访问,即使是父类没有用protected修饰的成员也可以。
private:
访问权限仅限于类的内部,是一种封装的体现,例如,大多数成员变量都是修饰符为private的,它们不希望被其他任何外部的类访问。
4、什么是LinkedHashSet()
A、是一个HashSet,保留了对象插入的顺序
B、是一个HashSet,拥有一个链表的性能
C、是一个HashSet,能很容易地转换为一个链表
D、HashSet对象的超类
正确答案:A
扩展:
LinkedHashSet是HashSet的一个“扩展版本”,HashSet并不管什么顺序,不同的是LinkedHashSet会维护“插入顺序”。HashSet内部使用HashMap对象来存储它的元素,而LinkedHashSet内部使用LinkedHashMap对象来存储和处理它的元素。
5、关于以下程序代码的说明正确的是()
public class HasStatic {
private static int x = 100;
public static void main(String args[]) {
HasStatic hs1 = new HasStatic();
hs1.x++;
HasStatic hs2 = new HasStatic();
hs2.x++;
hs1 = new HasStatic();
hs1.x++;
HasStatic.x--;
System.out.println("x=" + x);
}
}
A、5行不能通过编译,因为引用了私有静态变量
B、10行不能通过编译,因为x是私有静态变量
C、程序通过编译,输出结果为:x=103
D、 程序通过编译,输出结果为:x=102
正确答案:D
以下两个片段执行结果差异的原因是什么?
片段一:
short s=1;
s=s+1;
片段二:
short s=1;
s+=1;
可以自己组织一下答案,最后看结论
结论分析:
片段一自然是编译不通过的 ,提示损失精度 。
那么片段二为什么能编译通过呢?
隐式类型转换可以从小到大自动转,即byte->short->int->long,如果反过来会丢失精度,必须进行显示类型转换。
回到这一题来看,s+=1的意思与s = s+1不同,s=s+1这句先执行s+1然后把结果赋给s,由于1为int类型,所以s+1的返回值是int,编译器自动进行了隐式类型转换,所以将一个int类型赋给short就会出错。
而s+=1不同,由于他是使用+=操作符,在解析的时候s+=1就等价于s = (short)(s+1),也就是s+=1 <=> s = (s的类型)(s+1)。
(最后结论引自百度知道,略有删改。
解答出处:https://zhidao.baidu.com/question/250880637.html)
扩展:
基本类型数据及所占字节
数据类型 | 所占字节 |
boolean | 未定 |
byte | 1字节 |
char | 2字节 |
short | 2字节 |
int | 4字节 |
long | 8字节 |
float | 4字节 |
double | 8字节 |
隐式转换与显示转换概念
隐式类型转换
隐式转换也叫作自动类型转换, 由系统自动完成.
从存储范围小的类型到存储范围大的类型.
byte ->short(char)->int->long->float->double
显示类型转换
显示类型转换也叫作强制类型转换, 是从存储范围大的类型到存储范围小的类型.
当我们需要将数值范围较大的数值类型赋给数值范围较小的数值类型变量时,由于此时可能会丢失精度,因此,需要人为进行转换。我们称之为强制类型转换。
double→float→long→int→short(char)→byte
基本数据类型之间的转换规则
1.在一个双操作数以及位运算等算术运算式中,会根据操作数的类型将低级的数据类型自动转换为高级的数据类型,分为以下几种情况:
1)只要两个操作数中有一个是double类型的,另一个将会被转换成double类型,并且结果也是double类型;
2)只要两个操作数中有一个是float类型的,另一个将会被转换成float类型,并且结果也是float类型;
3)只要两个操作数中有一个是long类型的,另一个将会被转换成long类型,并且结果也是long类型;
4)两个操作数(包括byte、short、int、char)都将会被转换成int类型,并且结果也是int类型。
2. 如果低级类型为char型,向高级类型(整型)转换时,会转换为对应ASCII码值,再做其它类型的自动转换。
3. 对于byte,short,char三种类型而言,他们是平级的,因此不能相互自动转换,可以使用下述的强制类型转换。 如:
short i=99 ;
char c=(char)i;
System.out.println("output:"+c);
4. 不能在布尔值和任何数字类型间强制类型转换;
5. 不同级别数据类型间的强制转换,可能会导致溢出或精度的下降。
6. 当字节类型变量参与运算,java作自动数据运算类型的提升,将其转换为int类型。
例如:
byte b;
b=3;
b=(byte)(b*3);//必须声明byte。
来源参考: https://www.javazhiyin.com