JAVA基础面试

JAVA就业课程

一、面试整体流程

1.1 简单的自我介绍
我是xxxx,工作xxx年.我先后在xxxx公司、yyyy公司工作。先后做个xxxx项目、yyyy项目。
1.2 你简单介绍一下xxxx项目
为了解决xxxx问题,开发了一套xxxx系统,该系统主要有那些部分组成。简单介绍项目的整体架构。参与某个模块的开发。就要求你说一下这个模块的业务及设计。
1.3 会问一下JAVA的专业技能
后面详细讲解
1.4你还有什么需要询问我的吗
公司要做的项目?项目中会使用一下什么技术?

注意:经历了多轮面试后,对于你的自我介绍和项目项目经验面试官就不太关心了。
你说一下你最擅长的什么?你简单说一下?
最终技术面试完成后,都会让你回家等消息,或者等hr来和你谈薪资和福利。

二、java的专业技能

2.1 java的基础部分

2.1.1 简单讲一下java的跨平台原理
由于各操作系统(windows,liunx等)支持的指令集,不是完全一致的。就会让我们的程序在不同的操作系统上要执行不同程序代码。Java开发了适用于不同操作系统及位数的java虚拟机来屏蔽个系统之间的差异,提供统一的接口。对于我们java开发者而言,你只需要在不同的系统上安装对应的不同java虚拟机、这时你的java程序只要遵循java规范,就可以在所有的操作系统上面运行java程序了。

Java通过不同的系统、不同版本、不同位数的java虚拟机(jvm),来屏蔽不同的系统指令集差异而对外体统统一的接口(java API),对于我们普通的java开发者而言,只需要按照接口开发即可。如果我系统需要部署到不同的环境时,只需在系统上面按照对应版本的虚拟机即可。

2.1.2 搭建一个java开发环境的步骤
Java开发环境需要些什么?

1、适用于我们开发环境的jdk
2、对应开发环境eclipse
3、还需要web服务器(tomcat)

一、下载对应组件
二、安装
Jdk,安装正常流程安装即可,配置我们的JAVA_HOME,因为后面的eclispe和tomcat会依赖于这个变量.
Eclispe正常解压就ok,设置workspace的默认编码
Tomcat 正常解压就ok,把tomcat集成到eclispe中,安装插件就OK。

Svn/git

2.1.3讲一下java中int数据占几个字节
Java中有几种基本数据类型?8种

Int占 4个字节,32位
Boolean 1位

2.1.4 面向对象的特征有哪些方面
有四大基本特征:封装、抽象、继承、多态
面向对象的封装性,即将对象封装成一个高度自治和相对封闭的个体,对象状态(属性)由这个对象自己的行为(方法)来读取和改变。
张三这个人,他的姓名等属性,要有自己提供的获取或改变的方法来操作。private name setName getName
抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。 就是把现实生活中的对象,抽象为类。
在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。遗产继承
多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

Object obj = new xxx();
UserDao userDao = new UserDaoJdbcImpl();
UserDao userDao = new UserDaoHibernateImpl();
靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

原则:回答比较抽象问题的时候,要举例说明

2.1.5有了基本数据类型,为什么还需要包装类型?
基本数据类型,java中提供了8中基本的数据类型。boolean int float等

包装类型:每一个基本的数据类型都会一一对应一个包装类型。
boolean ----->Boolean
Int -------->Integer

装箱和拆箱
装箱:把基本的数据类型转换成对应的包装类型.
Integer .valueOf(1)
Integer i = 1;自动装箱,实际上在编译时会调用Integer .valueOf方法来装箱
拆箱:就是把包装类型转换为基本数据类型.基本数据类型 名称 = 对应的包装类型。
Integer i = 1;
int j = i;//自动拆箱//int j = i=intValue();手动拆箱
自动拆箱:实际上会在编译调用intValue

Java是一个面向对象的语言,而基本的数据类型,不具备面向对象的特性。
null Integer—>null int---->0 用Integer和int分别表示Person这个类的ID
Max 最大值
min 最小值
缓存值:对象缓存,Integer i=1; integer j= 1;i ==j

2.1.6、说一下"=="和equals方法究竟有什么区别?
非常经典的一个面试题?先说清楚一个,再来说另一个?
==用来判断两个变量之间的的值是否相等。变量就可以分为基本数据类型变量,引用类型。
如果是基本数据类型的变量直接比较值而引用类型要比较对应的引用的内存的首地址。

equals 用来比较两个对象长得是否一样。判断两个对象的某些特征是否一样。实际上就是调用对象的equals方法进行比较。

2.1.7讲一下String和StringBuilder的区别(final)?StringBuffer和StringBuilder的区别?

1.在java中提供三个类String StringBuillder StringBuffer来表示和操作字符串。字符串就是多个字符的集合。
String是内容不可变的字符串。String底层使用了一个不可变的字符数组(final char[])

String str =new String(“bbbb”);
而StringBuillder StringBuffer,是内容可以改变的字符串。StringBuillder StringBuffer底层使用的可变的字符数组(没有使用final来修饰)

2.最经典就是拼接字符串。
1、String进行拼接.String c = “a”+”b”;
2、StringBuilder或者StringBuffer
StringBuilder sb = new StringBuilder(); sb.apend(“a”).apend(“b”)

拼接字符串不能使用String进行拼接,要使用StringBuilder或者StringBuffer

3.StringBuilder是线程不安全的,效率较高.而StringBuffer是线程安全的,效率较低。

2.1.8、讲一下java中的集合?
Java中的集合分为value,key–vale(Conllection Map)两种。
存储值有分为List 和Set.
List是有序的,可以重复的。
Set是无序的,不可以重复的。根据equals和hashcode判断,也就是如果
一个对象要存储在Set中,必须重写equals和hashCode方法。
存储key-value的为map.

8、ArrayList和LinkedList的区别?
List常用的ArrayList和LinkedList。区别和使用场景?
ArrayList底层使用时数组。LinkedList使用的是链表。
数组查询具有所有查询特定元素比较快。而插入和删除和修改比较慢(数组在内存中是一块连续的内存,如果插入或删除是需要移动内存)。
链表不要求内存是连续的,在当前元素中存放下一个或上一个元素的地址。查询时需要从头部开始,一个一个的找。所以查询效率低。插入时不需要移动内存,只需改变引用指向即可。所以插入或者删除的效率高。

ArrayList使用在查询比较多,但是插入和删除比较少的情况,而LinkedList使用在查询比较少而插入和删除比较多的情况。

2.1.9讲一下HashMap哈HashTable的区别?HashTable和ConcurrentHashMap的区别?
相同点:HashMap和HasheTalbe都可以使用来存储key–value的数据。
区别:
1、HashMap是可以把null作为key或者value的,而HashTable是不可以的。
2、HashMap是线程不安全的,效率较高。而HashTalbe是线程安全的,效率较低。

?我想线程安全但是我又想效率高?
通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。

2.1.10、实现一个拷贝文件的工具类使用字节流还是字符流?
我们拷贝的文件不确定是只包含字符流,有可以能有字节流(图片、声音、图像等),为考虑到通用性,要使用字节流。

2.1.11、讲一下线程的几种实现方式?启动方式?区分方式?
①实现方式
1、通过继承Thread类实现一个线程
2、通过实现Runnable接口实现一个线程
继承扩展性不强,java总只支持单继承,如果一个类继承Thread就不能继承其他的类了。
②怎么启动?
Thread thread = new Thread(继承了Thread的对象/实现了Runnable的对象)
thread.setName(“设置一个线程名称”);
thread.start();
启动线程使用start方法,而启动了以后执行的是run方法。
③怎么区分线程?在一个系统中有很多线程,每个线程都会打印日志,我想区分是哪个线程打印的怎么办?
thread.setName(“设置一个线程名称”); 这是一种规范,在创建线程完成后,都需要设置名称。

2.1.12有没有使用过线程并发库?
简单了解过?
JDK5中增加了Doug Lea的并发库,这一引进给Java线程的管理和使用提供了强大的便利性。 java.util.current包中提供了对线程优化、管理的各项操作,使得线程的使用变得的心应手。该包提供了线程的运行,线程池的创建,线程生命周期的控制.

Java通过Executors提供四个静态方法创建四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

2.1.13线程池的作用?
1、限定线程的个数,不会导致由于线程过多导致系统运行缓慢或崩溃
2、线程池不需要每次都去创建或销毁,节约了资源、
3、线程池不需要每次都去创建,响应时间更快。
连接池也是一样?

2.1.14讲一下什么是设计模式?常用的设计模式有哪些?
设计模式就是经过前人无数次的实践总结出的,设计过程中可以反复使用的、可以解决特定问题的设计方法。

单例(饱汉模式、饥汉模式)
1、构造方法私有化,让出了自己类中能创建外其他地方都不能创建
2、在自己的类中创建一个单实例(饱汉模式是一出来就创建创建单实例,而饥汉模式需要的时候才创建)
3、提供一个方法获取该实例对象(创建时需要进行方法同步)
工厂模式:Spring IOC就是使用了工厂模式.
对象的创建交给一个工厂去创建。
代理模式:Spring AOP就是使用的动态代理。

2.2 java web部分

2.2.1讲一下http get和post请求的区别?

GET和POST请求都是http的请求方式,用户通过不同的http的请求方式完成对资源(url)的不同操作。GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作,具体点来讲GET一般用于获取/查询资源信息,而POST一般用于更新资源信息

1、Get请求提交的数据会在地址栏显示出来,而post请求不会再地址栏显示出来.
GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,多个参数用&连接;POST提交:把提交的数据放置在是HTTP包的包体中。 因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变
2、传输数据的大小
http Get请求由于浏览器对地址长度的限制而导致传输的数据有限制。而POST请求不会因为地址长度限制而导致传输数据限制。
3、安全性,POST的安全性要比GET的安全性高。由于数据是会在地址中呈现,所以可以通过历史记录找到密码等关键信息。
2.2.2 说一下你对servlet的理解?或者servlet是什么?
Servlet(Server Applet),全称Java Servlet, 是用Java编写的服务器端程序。而这些Sevlet都要实现Servlet这个借口。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。Servlet运行于支持Java的应用服务器中。

HttpServlet 重写doGet和doPost方法或者你也可以重写service方法完成对get和post请求的响应
2.2.3简单说一下servlet的生命周期?
servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。

加载Servlet的class---->实例化Servlet----->调用Servlet的init完成初始化---->响应请求(Servlet的service方法)----->Servlet容器关闭时(Servlet的destory方法)

Servlet启动时,开始加载servlet生命周期开始。Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候(服务器关闭)调用其destroy方法。

2.2.4 Servlet API中forward() 与redirect()的区别?
1、forward是服务器端的转向而redirect是客户端的跳转。
2、使用forward浏览器的地址不会发生改变。而redirect会发生改变。
3、Forward是一次请求中完成。而redirect是重新发起请求。
4、Forward是在服务器端完成,而不用客户端重新发起请求,效率较高。

2.2.5 JSP和Servlet有哪些相同点和不同点?
JSP是Servlet技术的扩展,所有的jsp文件都会被翻译为一个继承HttpServlet的类。也就是jsp最终也是一个Servlet.这个Servlet对外提供服务。

Servlet和JSP最主要的不同点在于JSP侧重于视图,Servlet主要用于控制逻辑。

Servlet如果要实现html的功能,必须使用Writer输出对应的html,比较麻烦。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件,做界面展示比较方便而嵌入逻辑比较复杂。

2.2.6 jsp有哪些内置对象?作用分别是什么?
9个内置的对象:
request 用户端请求,此请求会包含来自GET/POST请求的参数
response 网页传回用户端的回应
pageContext 网页的属性是在这里管理
session 与请求有关的会话期
application servlet正在执行的内容
out 用来传送回应的输出
config servlet的构架部件
page JSP网页本身
exception 针对错误网页,未捕捉的例外
四大作用域:pageContext request session application 可以通过jstl从四大作用域中取值.
Jsp传递值request session application cookie也能传值

2.2.7说一下session和cookie的区别?你在项目中都有哪些地方使用了?
Session和cookie都是会话(Seesion)跟踪技术。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。但是Session的实现依赖于Cookie,sessionId(session的唯一标识需要存放在客户端).
cookie 和session 的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中,比如购物车

购物车最好使用cookie,但是cookie是可以在客户端禁用的,这时候我们要使用cookie+数据库的方式实现,当从cookie中不能取出数据时,就从数据库获取。

2.2.8、MVC的各个部分都有那些技术来实现?
M(Model) 模型 javabean
V(View) 视图 html jsp volicity freemaker
C(Control) 控制器 Servlet,Action

Jsp+Servlet+javabean 最经典mvc模式,实际上就是model2的实现方式,就是把视图和逻辑隔离开来
Model1的方式 jsp+service+dao
MOdel2的方式 jsp+servlet+service+dao

使用struts2和springmvc这样的mvc框架后,jsp+核心控制器+action+javabean

2.3数据库部分

2.3.1数据库的分类及常用的数据库
数据库分为:关系型数据库和非关系型数据库
关系型:mysql oracle sqlserver等
非关系型:redis,memcache,mogodb,hadoop等
2.3.2简单介绍一下关系数据库三范式?
范式就是规范,就是关系型数据库在设计表时,要遵循的三个规范。
要想满足第二范式必须先满足第一范式,要满足第三范式必须先满足第二范式。

第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。列数据的不可分割

二范式(2NF)要求数据库表中的每个行必须可以被唯一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。(主键)

满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。(外键)

反三范式,有的时候为了效率,可以设置重复或者可以推导出的字段.
订单(总价)和订单项(单价)

2.3.3事务四个基本特征或 ACID 特性。
事务是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。
一个转账必须 A账号扣钱成功,B账号加钱成功,才算正真的转账成功。
事务必须满足四大特征:原子性,一致性,隔离性持久性/持续性
原子性:表示事务内操作不可分割。要么都成功、要么都是失败.
一致性:要么都成功、要么都是失败.后面的失败了要对前面的操作进行回滚。
隔离性:一个事务开始后,不能后其他事务干扰。
持久性/持续性:表示事务开始了,就不能终止。
2.3.4 mysql数据库的默认的最大连接数?
100
为什么需要最大连接数?特定服务器上面的数据库只能支持一定数目同时连接,这时候我们一般都会设置最大连接数(最多同时服务多少连接)。在数据库安装时都会有一个默认的最大连接数为100

2.3.5说一下msyql的分页?Oracle的分页?
为什么需要分页?在很多数据是,不可能完全显示数据。进行分段显示.

Mysql是使用关键字limit来进行分页的 limit offset,size 表示从多少索引去多少位.
Oracle的分页,大部分情况下,我们是记不住了。说思路,要使用三层嵌套查询。
Oracle的分页有点儿记不住了,只记得一些大概。是使用了三层嵌套查询。如果在工作中使用了,可以到原来的项目中拷贝或上网查询。

mysql:

String sql = 
"select * from students order by id limit " + pageSize*(pageNumber-1) + "," + pageSize;

oracle:

String sql = 
 "select * from " +  
 (select *,rownum rid from (select * from students order by postime desc) where rid<=" + pagesize*pagenumber + ") as t" + 
 "where t>" + pageSize*(pageNumber-1);

2.3.6简单讲一下数据库的触发器的使用场景?
触发器,需要有触发条件,当条件满足以后做什么操作。

触发器用处还是很多的,比如校内网、开心网、Facebook,你发一个日志,自动通知好友,其实就是在增加日志时做一个后触发,再向通知表中写入条目。因为触发器效率高。而UCH没有用触发器,效率和数据处理能力都很低。

每插入一个帖子,都希望将版面表中的最后发帖时间,帖子总数字段进行同步更新,用触发器做效率就很高。

create table board1(id int primary key auto_increment,name varchar(50),ar
ticleCount int);

create table article1(id int primary key auto_increment,title varchar(50)
,bid int references board1(id));

delimiter |#把分割符;改成|

create trigger insertArticle_Trigger after insert on article1 for each ro
w begin
-> update board1 set articleCount=articleCount+1 where id= NEW.bid;
-> end;
-> |

delimiter ;

insert into board1 value (null,‘test’,0);

insert into article1 value(null,‘test’,1);

2.3.7 简单讲一下数据库的存储过程的使用场景?
数据库存储过程具有如下优点:
1、存储过程只在创建时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次,因此使用存储过程可以大大提高数据库执行速度。
2、通常,复杂的业务逻辑需要多条 SQL 语句。这些语句要分别地从客户机发送到服务器,当客户机和服务器之间的操作很多时,将产生大量的网络传输。如果将这些操作放在一个存储过程中,那么客户机和服务器之间的网络传输就会大大减少,降低了网络负载。
3、存储过程创建一次便可以重复使用,从而可以减少数据库开发人员的工作量。
4、安全性高,存储过程可以屏蔽对底层数据库对象的直接访问,使用 EXECUTE 权限调用存储过程,无需拥有访问底层数据库对象的显式权限。

正是由于存储过程的上述优点,目前常用的数据库都支持存储过程,例如 IBM DB2,Microsoft SQL Server,Oracle,Access 等,开源数据库系统 MySQL 也在 5.0 的时候实现了对存储过程的支持。

定义存储过程:
create procedure insert_Student (_name varchar(50),_age int ,out _id int)
begin
insert into student value(null,_name,_age);
select max(stuId) into _id from student;
end;

call insert_Student(‘wfz’,23,@id);
select @id;

2.3.8 用jdbc怎么调用存储过程?
贾琏欲执事
加载驱动
获取连接
设置参数
执行
释放连接

package com.huawei.interview.lym;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;

public class JdbcTest {

/**
 * @param args
 */
public static void main(String[] args) {
	// TODO Auto-generated method stub
	Connection cn = null;
	CallableStatement cstmt = null;		
	try {
		//这里最好不要这么干,因为驱动名写死在程序中了
		Class.forName("com.mysql.jdbc.Driver");
		//实际项目中,这里应用DataSource数据,如果用框架,
		//这个数据源不需要我们编码创建,我们只需Datasource ds = context.lookup()
		//cn = ds.getConnection();			
		cn = DriverManager.getConnection("jdbc:mysql:///test","root","root");
		cstmt = cn.prepareCall("{call insert_Student(?,?,?)}");
		cstmt.registerOutParameter(3,Types.INTEGER);
		cstmt.setString(1, "wangwu");
		cstmt.setInt(2, 25);
		cstmt.execute();
		//get第几个,不同的数据库不一样,建议不写
		System.out.println(cstmt.getString(3));
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	finally
	{

		/*try{cstmt.close();}catch(Exception e){}
		try{cn.close();}catch(Exception e){}*/
		try {
			if(cstmt != null)
				cstmt.close();
			if(cn != null)				
				cn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

2.3.9常用SQL

2.3.10简单说一下你对jdbc的理解?
Java database connection java数据库连接.数据库管理系统(mysql oracle等)是很多,每个数据库管理系统支持的命令是不一样的。

Java只定义接口,让数据库厂商自己实现接口,对于我们者而言。只需要导入对应厂商开发的实现即可。然后以接口方式进行调用.(mysql + mysql驱动(实现)+jdbc)

2.3.11 写一个简单的jdbc的程序。写一个访问oracle数据的jdbc程序?
贾琏欲执事
加载驱动(com.mysql.jdbc.Driver,oracle.jdbc.driver.OracleDriver)
获取连接(DriverManager.getConnection(url,usernam,passord))
设置参数 Statement PreparedStatement
cstmt.setXXX(index, value);
执行 executeQuery executeUpdate
释放连接(是否连接要从小到大,必须放到finnaly)

2.3.12 JDBC中的PreparedStatement相比Statement的好处
大多数我们都使用PreparedStatement代替Statement
1:PreparedStatement是预编译的,比Statement速度快
2:代码的可读性和可维护性
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:
stmt.executeUpdate(“insert into tb_name (col1,col2,col2,col4) values (’”+var1+"’,’"+var2+"’,"+var3+",’"+var4+"’)");
perstmt = con.prepareStatement(“insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)”);
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
不用我多说,对于第一种方法,别说其他人去读你的代码,就是你自己过一段时间再去读,都会觉得伤心。

3:安全性
PreparedStatement可以防止SQL注入攻击,而Statement却不能。比如说:
String sql = “select * from tb_name where name= '”+varname+"’ and passwd=’"+varpasswd+"’";
如果我们把[’ or ‘1’ = ‘1]作为varpasswd传入进来.用户名随意,看看会成为什么?
select * from tb_name = ‘随意’ and passwd = ‘’ or ‘1’ = ‘1’;
因为’1’=‘1’肯定成立,所以可以任何通过验证,更有甚者:
把[’;drop table tb_name;]作为varpasswd传入进来,则:
select * from tb_name = ‘随意’ and passwd = ‘’;drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行。
而如果你使用预编译语句你传入的任何内容就不会和原来的语句发生任何匹配的关系,只要全使用预编译语句你就用不着对传入的数据做任何过虑。而如果使用普通的statement,有可能要对drop等做费尽心机的判断和过虑。
2.3.13 数据库连接池作用
1、限定数据库的个数,不会导致由于数据库连接过多导致系统运行缓慢或崩溃
2、数据库连接不需要每次都去创建或销毁,节约了资源
3、数据库连接不需要每次都去创建,响应时间更快。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值