Java基础笔试题

简答题

1 进程和线程有什么区别?用户线程和守护线程有什么区别?如何创建守护线程?

2 Spring框架中的三大核心思想是什么,并举例说出2个Spring中用到的设计模式

3 AOP有哪些使用场景,底层是如何实现的

4 简述MyBatis与Hibernate框架,并做对比

5 简述Struts2的工作原理,并说明struts2是如何实现mvc的

6 解释什么是XSS和CSRF

7 请简述synchronized和java.util.concurrent.locks.Lock的异同, 为什么调用object.wait()和object.notify()的时候要持有object的锁, wait()与sleep()的区别

8 ArrayList、Vector、LinkedList的存储性能和特性分别是什么

9 请简述cookie和session区别与联系

10 java 8 引入了哪些新特性 (说出2个以上即可)

11 写出几个常见的http状态码(如200 ok, 404 not found等)

12 什么是浅拷贝和深拷贝,java中如何实现深拷贝(写出一种方式即可,两种更佳)

13 简述java堆内存与栈内存的区别与联系,static变量存储在哪里

14 什么是Restful架构, 如何使用Spring实现restful

15 PL/SQL 中如何创建并调用 过程和函数,并说出两者之间的区别

16 oracle数据库有哪几种约束类型

17 oracle如何创建索引,使用索引需要注意些什么?什么是聚集索引和非聚集索引,对比二者的优缺点

18 解释并对比 并行和并发,同步和阻塞

19 写出JSP九大内置对象和四种JSP会话跟踪技术,以及Servlet的生命周期

20 介绍ajax XmlHttpRequest 对象常用的方法和属性

编程题

1 分别写一个饿汉式和懒汉式单例(注意线程并发和性能问题) [设计模式]

2 用java多线程的方式解决生产者消费者问题 [并发编程]

3 java编程实现一个多项式计算器(写出思路或伪代码即可), 包括加减乘除,括号即可,如 2-(1+2)*3+1/2=? [数据结构]

4 给出1,2,3,4,5六个数字,用java编写程序,打印出所有所有不同的排列,如12345,54321等。并给出算法的时间复杂度。[算法]

5 给出两个表 [数据库]

dept 部门表 列 id(部门id,主键), name(部门名称), address(地址)

emp 雇员表 列 emp_id(主键), dept_id(外键引用dept主键), name(姓名), sex(性别), salary(工资)

(1) 给出两个表的建表语句

(2) 统计平均薪资最高的前两个部门的 部门id,名称,平均薪资

(3) 部门计划对个别员工进行调薪,现在需要编写一个触发器,对于emp表中的salary进行合法性检查 要求 a 修改后数据大于之前数据 b 工资涨幅不超过10%

(4) 编写一个PL/SQL程序块,对姓名以A和S开头的雇员涨薪8%

参考答案

简答题

1 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序的单一进程。线程可以被称为轻量级进程。线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源。

当我们在Java程序中创建一个线程,它就被称为用户线程。一个守护线程是在后台执行并且不会阻止JVM终止的线程。当没有用户线程在运行的时候,JVM关闭程序并且退出。一个守护线程创建的子线程依然是守护线程。

Thread.setDeamon(true)

三大核心思想:IOC 反转控制,DI 依赖注入,AOP 面向切面

用到的设计模式:简单工厂(spring上下文bean创建), 工厂方法(例如spring配置文件中通过factory-method 指定静态方法来创建bean), 单例(Spring默认bean均为单例),代理(如使用动态代理实现AOP),观察者(如ContextLoaderListener),策略,模版方法(如jdbcTemplate)等,装饰器(如使用AOP织入新逻辑)

应用场景:日志记录,性能统计,安全控制,事务处理,异常处理

实现AOP的方法: 1 动态代理(运行期间) 2 动态字节码生成(使用cglib) 3 自定义类加载器 4 使用java Instrumentation特性,在字节码加载到jvm前进行字节码转换

4 Hibernate对数据库结构提供了较为完整的封装,Hibernate的O/R Mapping实现了POJO 和数据库表之间的映射,以及SQL 的自动生成和执行。程序员往往只需定义好了POJO 到数据库表的映射关系,即可通过Hibernate 提供的方法完成持久层操作。程序员甚至不需要对SQL 的熟练掌握, Hibernate/OJB 会根据制定的存储逻辑,自动生成对应的SQL 并调用JDBC 接口加以执行。

iBATIS 的着力点,则在于POJO 与SQL之间的映射关系。然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定POJO。 相对Hibernate“O/R”而言,iBATIS 是一种“Sql Mapping”的ORM实现。

相同点:

(1) Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。

(2) Hibernate和MyBatis都支持JDBC和JTA事务处理。

(3) Hibernate和MyBatis,可以使用第三方缓存。

不同点:

(1) MyBatis可以进行更为细致的SQL优化,可以减少查询字段。

(2) MyBatis容易掌握,而Hibernate门槛较高。

(3) Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。

(4) Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL

struts 2基本工作原理(简述即可,不需要过于详细):

(1) 客户端发出一个指向servlet容器的请求(tomcat);

(2) 这个请求会经过图中的几个过滤器,最后会到达FilterDispatcher过滤器。

(3) 过滤器FilterDispatcher是struts2框架的心脏,在处理用户请求时,它和请求一起相互配合访问struts2的底层框架结构。在web容器启动时,struts2框架会自动加载配置文件里相关参数,并转换成相应的类。如:ConfigurationManager、ActionMapper和ObjectFactory。ConfigurationManager 存有配置文件的一些基本信息,ActionMapper存有action的配置信息。在请求过程中所有的对象(Action,Results,Interceptors,等)都是通过ObjectFactory来创建的。过滤器会通过询问ActionMapper类来查找请求中需要用到的Action。

(4) 如果找到需要调用的Action,过滤器会把请求的处理交给ActionProxy。ActionProxy为Action的代理对象。ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类。

(5) ActionProxy创建一个ActionInvocation的实例。ActionInvocation在ActionProxy层之下,它表示了Action的执行状态,或者说它控制的Action的执行步骤。它持有Action实例和所有的Interceptor。

(6) ActionInvocation实例使用命名模式来调用,a. ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。b. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor。在

调用Action的过程前后,涉及到相关拦截器(intercepetor)的调用。

(7) 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。

Struts2是这样实现mvc的

在struts2中,Model对应业务逻辑组件,它通常用于实现业务逻辑方法以及以及与底层数据库的交互等;View对应视图组件,通常是指JSP页面,但也适用于其他视图显示技术,如Velocity或者Excel文档;Control对应系统核心控制器和业务逻辑控制器,系统核心控制器为Struts2框架提供的FilterDispatcher,它根据请求自动调用相应的Action。而业务逻辑控制器是指开发人员自行定义的一系列Action,在Action中负责调用相应的业务逻辑组件来完成处理。

6 XSS:跨站脚本(Cross-site scripting)

是注入攻击的一种。其特点是不对服务器端造成任何伤害,而是通过一些正常的站内交互途径,例如发布评论,提交含有JavaScript 的内容文本。这时服务器端如果没有过滤或转义掉这些脚本,作为内容发布到了页面上,其他用户访问这个页面的时候就会运行这些脚本。

CSRF:跨站请求伪造(Cross-site request forgery) 通过伪装来自受信任用户的请求来利用受信任的网站

7 Lock接口比同步方法和同步块提供了更具扩展性的锁操作。他们允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的条件对象。

它的优势有:

(1) 可以使锁更公平

(2) 可以使线程在等待锁的时候响应中断

(3) 可以让线程尝试获取锁,并在无法获取锁的时候立即返回或者等待一段时间

(4) 可以在不同的范围,以不同的顺序获取和释放锁

因为wait和notify在调用时会释放当前持有锁

Wait与sleep区别

Wait是Object方法,sleep是Thread方法,sleep不释放锁,只是暂停执行一段时间后继续运行。而wait会释放锁,何时运行取决于cpu调度。

8 ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

9区别

(1) cookie是保存在浏览器的内存中,而session则是保存在服务器端。

(2) session与cookie相比,当你登陆访问页面的时候,使用cookie可以自动登录,如果有人另外一个客户端同时登录。这个时候,服务器就会检查其session ID。如果已经有相同的session ID登录,就不会允许再登录。这样可以防止同一用户多次登录,保障公司的利益。

(3) 用户可以通过在浏览器设置不保存cookie,而当用户登录时,服务器会将session ID以密文的形式写在HTTP的响应报头,从而实现访问的上下连贯。

(4) cookie放置在浏览器内存中,使用起来更加灵活方便,session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能

(5) SESSION是保存在服务端的;Cookie是保存在客户机器上的Session不可伪造;Cookie可以伪造!并且session不传递,因此,session比cookie更加的安全。

联系

二者都可以用来保存用户的信息, Session的使用要求用户浏览器必须支持Cookie,

如果浏览器不支持使用Cookie,或者设置为禁用Cookie,那么将不能使用Session。用户在进行访问时,服务器会通过查找session,将用户的session ID传给浏览器,而浏览器则将这个ID以cookie的形式保存在浏览器的内存中。也可以说cookie是session在浏览器中的标识。当然也可以以其他的方式保存

10 (1) 接口默认方法 (2) lambda表达式 (3) 函数式接口 等

11 举例如下,不限于以下结果:

200 OK //客户端请求成功

400 Bad Request //客户端请求有语法错误,不能被服务器所理解

401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用

403 Forbidden //服务器收到请求,但是拒绝提供服务

404 Not Found //请求资源不存在,eg:输入了错误的URL

500 Internal Server Error //服务器发生不可预期的错误

503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

12 浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。

Java实现深拷贝的方法:1 重写clone方法 2 序列化后解序列化

13 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。

堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。

引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!

Static变量存储在静态区中

14表现层状态转移

用url标识一个资源,用http四种请求POST,DELETE,PUT,GET代表增删改查

Controller使用PathVariable注解绑定url中的变量,RequestMapping中method代表具体操作类型(POST,DELETE,PUT,GET),配置前端模版,如jsp或freemarker作为表现层展示。

15

创建函数

CREATE [OR REPLACE] FUNCTION function_name

(arg1 [ { IN | OUT | IN OUT }] type1 [DEFAULT value1],

[arg2 [ { IN | OUT | IN OUT }] type2 [DEFAULT value1]],

......

[argn [ { IN | OUT | IN OUT }] typen [DEFAULT valuen]])

[ AUTHID DEFINER | CURRENT_USER ]

RETURN return_type

IS | AS

<类型.变量的声明部分>

BEGIN

执行部分

RETURN expression

EXCEPTION

异常处理部分

END function_name;

调用函数

与程序中函数的调用方法一致

创建存储过程

CREATE [OR REPLACE] PROCEDURE procedure_name

([arg1 [ IN | OUT | IN OUT ]] type1 [DEFAULT value1],

[arg2 [ IN | OUT | IN OUT ]] type2 [DEFAULT value1]],

......

[argn [ IN | OUT | IN OUT ]] typen [DEFAULT valuen])

[ AUTHID DEFINER | CURRENT_USER ]

{ IS | AS }

<声明部分>

BEGIN

<执行部分>

EXCEPTION

<可选的异常错误处理程序>

END procedure_name;、

调用存储过程

EXEC[UTE] procedure_name( parameter1, parameter2…);

区别:

1、如果需要返回多个值和不返回值,就使用过程;如果只需要返回一个值,就使用函数。

2、过程一般用于执行一个指定的动作,函数一般用于计算和返回一个值。

3、可以SQL语句内部(如表达式)调用函数来完成复杂的计算问题,但不能调用过程。所以这是函数的特色。

16 1.主键约束2.外键约束3.唯一约束4.检查约束5.非空约束

17 CREATE INDEX 索引名 ON 表名 (列名)

索引本身会提升查询速度,但是索引建立过多会影响DML语句速度,造成额外存储开销和索引更新消耗

聚集索引:物理存储按照索引排序

非聚集索引:物理存储不按照索引排序

聚集索引:插入数据时速度要慢(时间花费在“物理存储的排序”上,也就是首先要找到位置然后插入),查询数据比非聚集数据的速度快

18 并发的实质是一个物理CPU(也可以多个物理CPU) 在若干道程序之间多路复用,并发性是对有限物理资源强制行使多用户共享以提高效率。

并行性指两个或两个以上事件或活动在同一时刻发生。在多道程序环境下,并行性使多个程序同一时刻可在不同CPU上同时执行。

阻塞是指当操作系统存在对内核调用时,操作系统将数据从内核加载到用户缓冲区这个过程中发生的等待。同步是指数据从用户缓冲区数据加载完成到用户进程去缓冲区取数据这个阶段发生的等待。

19 九大内置对象

request 请求对象

response 响应对象

pageContext 页面上下文对象

session 会话对象 application

out 输出对象

config 配置对象

page 页面对象

exception 例外对象

四种会话跟踪

(1) page是代表与一个页面相关的对象和属性。一个页面有一个编译好的Java Servlet类(可以带有任何的include指令,但是没有include动作)表示。这既包括servlet又包括被编译成servlet的JSP页面。

(2) request是代表与Web客户机发出的一个请求相关的对象和属性,一个请求可能跨越多个页面,涉及多个Web组件(由于forward指令和include动作的关系)

(3) session是代表与用于某个web客户机的一个用户体验相关的对象和属性。一个Web回话可以也经常会跨越多个客户机请求。

(4) application是代表与整个web应用程序想关的对象和属性,着实质上是跨越整个web应用程序,包括多个页面、请求和会话的一个全局作用域。

Servlet生命周期

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

(2) 响应客户请求阶段  调用service()方法

(3) 终止阶段  调用destroy()方法

20 属性

readyState属性

当XMLHttpRequest对象被创建后,readyState属性标识了当前对象所处的状态,具体的值代表意义如下:

0 未初始化状态,此时仅创建了一个XMLHttpRequest对象。

1 初始化状态,即调用了open()方法后的准备发送状态。

2 已发送状态,即调用了send()方法后,以把一个请求发送到服务器端,但是还未收到响应。

3 正在接收状态,正在接收从服务器端发送回来的数据,但还未接收完所处的状态。

4 完成响应状态,以完成了HttpResponse响应的接收。

responseText属性

当readyState属性值为4时,该属性才包含完整的响应信息,以纯文本数据形式返回。

responseXML属性

当readyState属性值为4时,并且响应头部的Content-Type的MIME类型被指定为XML(text/xml或者application/xml)时,

该属性才会有值并且被解析为一个XML文档。

status属性

该属性描述了HTTP状态码。注意,仅当readyState属性值为3或4时,才能对此属性进行访问。

statusText属性

该属性描述的是HTTP状态码文本。

onreadystatechange属性

每当readyState属性值发生改变时,就会触发该事件,一般是通过该事件来触发回调函数。

方法

open()方法

初始化XMLHttpRequest对象,设置连接信息。

send()方法

发送数据,开始和服务器端进行交付。

abort()方法

暂停一个http的请求发送或接收,并且将XMLHttpRequest对象设置为初始化状态。

setRequestHeader()方法

该方法用来设置请求的头部信息,"Content-Type","application/x-www-form-urlencoded"。

getResponseHeader()方法

此方法用于检索响应的头部值,此外还可以通过getAllResponseHeaders()方法获取所有的头部信息。

编程题

1 饿汉式单例比较简单,程序加载时直接创建,不需要考虑并发访问

懒汉式单例参考代码

public class SingleDemo {

private static SingleDemo s = null;

private SingleDemo(){}

public static SingleDemo getInstance(){

/*如果第一个线程获取到了单例的实例对象,

* 后面的线程再获取实例的时候不需要进入同步代码块中了*/

if(s == null){

//同步代码块用的锁是单例的字节码文件对象,且只能用这个锁

synchronized(SingleDemo.class){

if(s == null){

s = new SingleDemo();

}

}

}

return s;

}

}

2 四种方式 (不限于以下四种)

(1) wait和notify

(2) Await和signal

(3) 使用阻塞队列

(4) 使用Lock,以及竞态条件

3 多项式计算器

步骤: 1 中缀转后缀 2 利用栈辅助进行后缀表达式的计算

4 思路: 利用图遍历或者递归方式可解

5 略

猜你喜欢

转载自sunrysoft.iteye.com/blog/2357379