百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

java 常见笔试题(一) java笔试题一般考什么

yuyutoo 2024-10-26 16:09 7 浏览 0 评论

笔者在工作的过程中,面试过许多人也被面试过,这个系列文章会总结java开发中常见的笔试题及答案,难度有深有浅,希望对找工作的小伙伴有所帮助。

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)

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

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

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

实现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

5 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 略

相关推荐

12、高阶组件:魔法增幅器——React 19 HOC模式

一、魔法增幅器的本质"高阶组件是魔法师用咒语叠加的炼金术,"霍格沃茨魔咒研究院院长凝视着发光的增幅器,"通过函数式能量场的嵌套,让基础组件获得预言家日报式的逻辑继承!"...

深入理解nodejs的异步IO与事件模块机制

一、node为什么要使用异步I/O异步最先诞生于操作系统的底层,在底层系统中,异步通过信号量、消息等方式有广泛的应用。但在大多数高级编程语言中,异步并不多见,这是因为编写异步的程序不符合人习惯的思维逻...

前端时间同步利器:React + useEffect 实现高性能动态时钟

前言在你奋笔疾敲代码的瞬间,是不是突然一低头,发现时间像偷偷跑路的变量,一眨眼就从上午飘到下午?饭没吃、会没开、工位也快被前端猫霸占了。仿佛你写的不是代码,而是“时间穿梭机”。别慌,咱们今天就来用R...

JavaScript 异步编程指南 - 聊聊 Node.js 中的事件循环

作者:五月君来源:编程界|事件循环是一种控制应用程序的运行机制,在不同的运行时环境有不同的实现,上一节讲了浏览器中的事件循环,它们有很多相似的地方,也有着各自的特点,本节讨论下Node.js中...

10个Vue开发技巧「实践」

作者:WahFung转发链接:https://juejin.im/post/5e8a9b1ae51d45470720bdfa路由参数解耦一般在组件内使用路由参数,大多数人会这样做:...

通过番计时器实例学习 React 生命周期函数 componentDidMount

大家好,今天我们将通过一个实例——番茄计时器,学习下如何使用函数生命周期的一个重要函数componentDidMount():componentDidMount(),在组件加载完成,render之后...

SRE监控四大黄金指标,任何一个有异常都会是灾难……

导读...

前端必看!10 个 Vue3 救命技巧,解决你 90% 的开发难题?

写Vue3项目时,是不是总被数据更新延迟、组件间传值混乱、页面加载缓慢这些问题折磨得头秃?别担心!作为摸爬滚打多年的老前端,今天掏出压箱底的10个实战技巧,从性能优化到复杂逻辑处理,每一个都能...

如何用2 KB代码实现3D赛车游戏?2kPlus Jam大赛了解一下

选自frankforce作者:Frank机器之心编译参与:王子嘉、GeekAI控制复杂度一直是软件开发的核心问题之一,一代代的计算机从业者纷纷贡献着自己的智慧,试图降低程序的计算复杂度。然而,将一款...

证明你访问的网站是你想访问的,Safari 真的需要

安全研究员在Safari上找到了一个新漏洞,能让网站在浏览器的地址栏内将自己伪装成另一个网站——得益于Safari地址栏的“智能缩略”功能。在Deusen最近公开的攻击演示(PoC,P...

抓狂!TS 组件性能拉胯到崩溃?4 个绝杀技巧逆风翻盘!

前端兄弟姐妹们五一假期快乐,咱们谁还没被TypeScript组件的性能问题折磨过?页面加载转圈圈,点击按钮没反应,代码改了一轮又一轮,性能却还是原地踏步,分分钟想砸电脑!别慌,今天这4个绝杀技...

让小球做圆周运动,你有几种办法?

最近在阅读外国技术文章中无意中发现了一个神奇的CSS属性motion-path,它可以让Dom元素可以按照自定义的路径移动。又想起了很久之前参加校招面试的时候,面试官问了我一个问题“能不能不借助库实现...

前端基础进阶(十四):深入核心,详解事件循环机制

EventLoopJavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了。为了解决自己的这个困扰,在学习的过程中,我一直在试图寻...

从0搭建一个WebRTC,实现多房间多对多通话,并实现屏幕录制

这篇文章开始会实现一个一对一WebRTC和多对多的WebRTC,以及基于屏幕共享的录制。本篇会实现信令和前端部分,信令使用fastity来搭建,前端部分使用Vue3来实现。为什么要使用WebRTCWe...

Vue2 开发卡壳?这 10 个实战技巧专治各种不服

干前端开发的兄弟,谁还没被Vue2折腾过?数据不更新、组件通信乱成麻、性能差到想砸电脑……这些痛点,我都懂!今天直接甩出10个超实用的实战技巧,每一个都是从项目“血坑”里爬出来总结的,专...

取消回复欢迎 发表评论: