Java面试(4)
1 哈希函数满足什么条件?
计算简单/散列地址分布均匀。
3 System.gc() VS Runtime.gc()
java.lang.System.gc()只是java.lang.Runtime.getRuntime().gc()的简写
提示JVM进行垃圾回收。但是不保证立即执行。
4 finalize() 什么时候调用?
在释放对象占用的内存之前,垃圾收集器会调用对象的finalize()方法,一般建议在该方法中释放对象持有的资源。
5 对象的引用设置为null,垃圾收集器是否立即释放对象占用的内存。
不会。在下个垃圾回收周期中,这个对象将是可被回收的。
6 JDBC
JDBC允许用户在不同的数据库之间做选择的一个抽象层。JDBC允许开发者用JAVA写数据库应用程序,而不关心底层数据库细节。
package interview; import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; public class JDBCTest { public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.driver");
} catch (ClassNotFoundException e) {
System.out.println("找不到驱动程序类 ,加载驱动失败!");
}
// JDBC连接的URL:协议:子协议:数据源标识
String url = "jdbc:mysql://localhost:3306/test?useUicode=true"; // 创建数据库连接
String username = "root";
String password = "root"; Connection con = null;
try {
con = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
System.out.println("数据库连接失败!");
e.printStackTrace();
} /*
* 创建statement: 要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3 种类型:
* 1、 执行静态SQL语句。通常通过Statement实例实现。 2、
* 执行动态SQL语句通常通过PreparedStatement实例实现。 3、
* 执行数据库存储过程。通常通过CallableStatement实例实现。
* 注意:在SQL中如果某些参数没有确定,如"select * from t1 where c1>? and c2<?",这种语句是静态SQL
* ,不是动态SQL,虽然个别参数的值不知道,但整个SQL的结构已经确定,数据库是可以将它编译的,在执行阶段只需将个别参数的值补充进来即可
* 具体的实方式:
*/ Statement stmt = null;
try {
stmt = con.createStatement();
PreparedStatement pstmt = con.prepareStatement(sql);
CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}"); } catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} /*
* 执行SQL: Statement接口三种SQL方法:executeQuery, executeUpdate, execute
* ResultSet executeQuery(String sql) : 查询,返回结果集。 Int
* executeUpdate(String sql) : insert/update/delete, DDL(create table,
* drop table) Execute(sql) : 返回多个结果集,多个更新计数或二者结合的语句。
*/
ResultSet rs = stmt.executeQuery("xx");
int rows = stmt.executeUpdate("xx");
Boolean flag = stmt.execute("xxx"); // 处理结果:
while (rs.next()) {
String name = rs.getString("name"); //
String pass = rs.getString(1); // 这个方法高效,列是从左到右,从1开始
} // 关闭JDBC对象
// 关闭记录集 ->关闭声明->关闭连接对象。
if (rs != null) { // 关闭记录集
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) { // 关闭声明
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) { // 关闭连接对象
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
7 驱动(driver)在JDBC中的角色
JDBC驱动提供了特定厂商对JDBC API接口类的实现。
驱动必须提供java.sql包下面这些类的实现:
Connection, Statement, PreparedStatement, CallableStatement, ResutlSet, Driver
8 PreparedStatement 比 Statement有什么优势?
PreparedStatement是预编译的,性能好。Connection.preparedStatment(sql)方法执行可以获得一个PreparedStatement对象,数据库系统会对sql语句进行预编译,预编译后可以重复用,这样它比
Statement对象生成的查询速度更快。适合多次执行。
优点:执行带参数的sql语句。
性能更好,SQL语句会预编译在数据库系统中,执行计划(索引等)同样会被缓存,允许参数化查。
询,使用预处理语句比普通的查询更快(因为对SQL语句的分析,编译,优化已经在第一次查询的时候完成了)
Statement:不能参数化,通用查询,每次都要编译,再执行。适合一次执行。
PreparedStatement:参数话查询,
CallableStatement:存储过程。
在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement.
基于以下的原因:
每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个函数)就会得到执行.这并不是说只有一个
Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.
最重要一定:极大的提高安全性:
String sql
= "select * from tb_name where name= '"+varname+"' and
passwd='"+varpasswd+"'";
如果我们把[' or '1'
= '1]作为varpasswd传入进来.用户名随意,看看会成为什么?
select *
from tb_name = 'XXX' and passwd = '' or '1' = '1';
把[';drop table tb_name;]作为varpasswd传入进来,则:
而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.(前提是数据库本身支持预编译,但上前可能没有什么服务端数据库不支持编译了,只有少数的桌面数据库,就是直接文件访问的那些)只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement, 有可能要对drop,;等做费尽心机的判断和过虑.
登录的时候在用户输入框写上:张三'# 然后密码框任意填:njksad
select*
from users where username='张三'#' and
password='njksad'
上述语句中 ”#“表示注释,那么只有用户名不用密码救能访问DB了。
9 如何避免SQL注入攻击?
下面两条是SQL注入的例子:
select * from school.COURSE where cno='1' and cname='name' or 1 = 1
select * from school.COURSE where cno='1'# and cname='name' or 1 = 1
Statement有一个子类叫做PreparedStatement:
PreparedStatement是Statement的孩子,不同的是,PreparedStatement使用预编译机制,在创建PreparedStatement对象时就需要将sql语句传入,传入的过程中参数要用?替代,这个过程回导致传入的sql被进行预编译,然后再调用PreparedStatement的setXXX将参数设置上去,由于sql语句已经经过了预编译,再传入特殊值也不会起作用了。
而且PreparedStatement使用了预编译机制,sql语句在执行的过程中效率比Statement要高。
之所以PreparedStatement能防止注入,是因为它把单引号转义了,变成了\',这样一来,就无法截断SQL语句,进而无法拼接SQL语句,基本上没有办法注入了。
10 什么时候用CallableStatement? 用来准备CallableStatement的方法是什么?
CallableStatement用来执行存储过程。存储过程是由数据库存储和提供的。存储过程可以接收输入参数,也可以有返回结果。 CallableStatement.prepareCall()。
11 数据库连接池
打开/关闭数据库连接浪费时间,成本高。可以再应用服务器启动的时候建立多个数据库连接并维护在一个池中。
连接池就是一个装满了CONNECTION的容器。
你可以自定义通过drivermanager拿到多少个连接,每拿到一个连接,你可以把这些连接封装到一个集合(LIST,SET等),拿到你觉得适合的个数就可以了,当然每次执行完一次SQL请求,这些连接将会还回连接池,而不是直接还给数据库。
12 java 不可变类
因为不可变的对象默认就是线程安全的,他们一旦创建就不能发生改变
immutable Objects就是那些一旦被创建,它们的状态就不能被改变的Objects,每次对他们的改变都是产生了新的immutable的对象,而mutable Objects就是那些创建后,状态可以被改变的Objects.
举个例子:String和StringBuilder,String是immutable的,每次对于String对象的修改都将产生一个新的String对象,而原来的对象保持不变,而StringBuilder是mutable,因为每次对于它的对象的修改都作用于该对象本身,并没有产生新的对象。
实际上JDK本身就自带了一些immutable类,比如String,Integer以及其他包装类。为什么说String是immutable的呢?比如:java.lang.String 的trim,uppercase,substring等方法,它们返回的都是新的String对象,而并不是直接修改原来的对象。
要写出这样的类,需要遵循以下几个原则:
1)immutable对象的状态在创建之后就不能发生改变,任何对它的改变都应该产生一个新的对象。
2)Immutable类的所有的属性都应该是final的。
3)对象必须被正确的创建,比如:对象引用在对象创建过程中不能泄露(leak)。
4)对象应该是final的,以此来限制子类继承父类,以避免子类改变了父类的immutable特性。
5)如果类中包含mutable类对象,那么返回给客户端的时候,返回该对象的一个拷贝,而不是该对象本身(该条可以归为第一条中的一个特例)
使用Immutable类的好处:
1)Immutable对象是线程安全的,可以不用被synchronize就在并发环境中共享
2)Immutable对象简化了程序开发,因为它无需使用额外的锁机制就可以在线程间共享
3)Immutable对象提高了程序的性能,因为它减少了synchroinzed的使用
4)Immutable对象是可以被重复使用的,你可以将它们缓存起来重复使用,就像字符串字面量和整型数字一样。你可以使用静态工厂方法来提供类似于valueOf()这样的方法,它可以从缓存中返回一个已经存在的Immutable对象,而不是重新创建一个。
缺点是:产生大量垃圾。
因为string是不可变的,所以绝对安全,是线程安全的。StringBuilder实际上自身维护一个char[]数组,append是没有synchronized。StringBuffer的append等很多操作都是带有synchronized的,所以同样线程安全。
所以单线程字符串拼接一般采用StringBuilder,效率高。多线程环境则采用Stringbuffer,虽然安全,但是相对效率会低些。
Java面试(4)的更多相关文章
- JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结
我是一名java开发人员,hibernate以及mybatis都有过学习,在java面试中也被提及问道过,在项目实践中也应用过,现在对hibernate和mybatis做一下对比,便于大家更好的理解和 ...
- 转:最近5年133个Java面试问题列表
最近5年133个Java面试问题列表 Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来 ...
- java面试宝典(蓝桥学院)
Java面试宝典(蓝桥学院) 回答技巧 这套面试题主要目的是帮助那些还没有java软件开发实际工作经验,而正在努力寻找java软件开发工作的学生在笔试/面试时更好地赢得好的结果.由于这套试题涉及的范围 ...
- JAVA面试精选【Java基础第一部分】
这个系列面试题主要目的是帮助你拿轻松到offer,同时还能开个好价钱.只要能够搞明白这个系列的绝大多数题目,在面试过程中,你就能轻轻松松的把面试官给忽悠了.对于那些正打算找工作JAVA软件开发工作的童 ...
- Java面试必备知识
JAVA面试必备知识 第一,谈谈final, finally, finalize的区别. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可 ...
- java面试和笔试大全 分类: 面试 2015-07-10 22:07 10人阅读 评论(0) 收藏
2.String是最基本的数据类型吗? 基本数据类型包括byte.int.char.long.float.double.boolean和short. java.lang.String类是final类型 ...
- 近5年133个Java面试问题列表
Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来越高级,面试官问的问题也更深入. 在我 ...
- java 面试
115个Java面试题和答案——终极列表(上) 本文我们将要讨论Java面试中的各种不同类型的面试题,它们可以让雇主测试应聘者的Java和通用的面向对象编程的能力.下面的章节分为上下两篇,第一 ...
- 【Java面试】基础知识篇
[Java面试]基础知识篇 Java基础知识总结,主要包括数据类型,string类,集合,线程,时间,正则,流,jdk5--8各个版本的新特性,等等.不足的地方,欢迎大家补充.源码分享见个人公告.Ja ...
- JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结(转)
hibernate以及mybatis都有过学习,在java面试中也被提及问道过,在项目实践中也应用过,现在对hibernate和mybatis做一下对比,便于大家更好的理解和学习,使自己在做项目中更加 ...
随机推荐
- mysql中的过滤分组
本文节选自<MYSQL必知必会> 一. 过滤分组 除了能用GROUP BY分组数据外,MySQL还允许过滤分组,规定包括哪些分组,排除哪些分组.例如,可能想要列出至少有两个订单的所有顾客. ...
- Python 用Redis简单实现分布式爬虫
Redis通常被认为是一种持久化的存储器关键字-值型存储,可以用于几台机子之间的数据共享平台. 连接数据库 注意:假设现有几台在同一局域网内的机器分别为Master和几个Slaver Master连接 ...
- [MYSQL]时间毫秒数转换
java中常用bigint字段保存时间,通常将时间保存为一大串数字,每次取出需要在程序里转换,有时候程序里不方便,可以使用MYSQL自带的函数FROM_UNIXTIME(unix_timestamp, ...
- opencv:图像模糊处理
接口: blur(sourceImage,dstImage,Size(,)); // 图像模糊处理 示例代码: #include <opencv.hpp> #include <img ...
- msbuild编译
@echo offcd /d %~dp0 if exist output.log del /q /f output.logif exist success.txt del /q /f success. ...
- mysql-5.7.17的最新安装教程
mysql-5.7.17-winx64是现在最新版本的Mysql,这是免安装的,所以要进行些配置 下载地址:https://cdn.mysql.com//Downloads/MySQL-5.7/mys ...
- OC-常见归档总结
/***** 该文一共总结了以下六种文件操作 1.NSKeyedArchiver. 2.对类对象进行归档 <NSCoder>协议 3.文件管理类 NSFileManger 4.对文 ...
- Flask的请求与响应
Flask的请求与响应 1 请求相关信息 request.method # 请求方法 request.args # get 请求的参数 request.form # post请求的参数 request ...
- 在 Ubuntu 上搭建 Hadoop 分布式集群 Eclipse 开发环境
一直在忙Android FrameWork,终于闲了一点,利用空余时间研究了一下Hadoop,并且在自己和同事的电脑上搭建了分布式集群,现在更新一下blog,分享自己的成果. 一 .环境 1.操作系统 ...
- How your script code be coverted into arm code and running on ios.
Your script code is compiled into DLLs (assemblies) by the editor. When you build for iOS, these ass ...