1. System.out.println("str".getClass().getName())输出什么?
答:输出java.lang.String ,因为str是字符串
2.以下哪个HTTP头信息与浏览器缓存无关
A. Etag B.Upgrade C. Explire D Last-Modified
答:B
常见的响应头:
Location: http://www.lks.cn/index.html
控制浏览器显示哪个页面
Server:apache nginx
服务器的类型
Content-Encoding: gzip
服务器发送的压缩编码方式
Content-Length: 80
服务器发送显示的字节码长度
Content-Language: zh-cn
服务器发送内容的语言和国家名
Content-Type: image/jpeg; charset=UTF-8
服务器发送内容的类型和编码类型
Last-Modified: Tue, 11 Jul 2000 18:23:51GMT 服务器最后一次修改的时间
Refresh: 1;url=http://www.lks.cn
控制浏览器1秒钟后转发URL所指向的页面
Content-Disposition: attachment; filename=lks.jpg 服务器控制浏览器发下载方式打开文件
Transfer-Encoding: chunked
服务器分块传递数据到客户端
Set-Cookie:SS=Q0=5Lb_nQ; path=/search 服务器发送Cookie相关的信息
Expires: -1
资源的过期时间,提供给浏览器缓存数据,-1永远过期
Cache-Control: no-cache
告诉浏览器,一定要回服务器校验,不管有没有缓存数据。
Pragma: no-cache
服务器控制浏览器不要缓存网页
Connection: close/Keep-AliveHTTP
请求的版本的特点
Date: Tue, 11 Jul 2000 18:23:51 GMT 响应网站的时间
ETag:“ihfdgkdgnp98hdfg” 资源实体的标识(唯一标识,类似md5值,文件有修改md5就不一样)
关于缓存相关头的解释:
Expires
一个GMT时间,试图告知浏览器,在此日期内,可以信任并使用对应缓存中的副本,缺点是,一但客户端日期不准确.则可能导致失效.
Pragma : no-cache
这个是http1.0中的常规头,作用同http1.1的 Cache-Control : no-cache
Last-Modified
一个GMT时间,告知被请求实体的最后修改时间.用于浏览器校验其缓存副本是否仍然可以信任.与其相关的两个条件请求标头:
1)
If-Modified-Since
仅在get方法中意义,这个也是比较常见的。 如果实体在指定时间后,没有修改则返回一个304,否则返回一个常规的Get请求的响应(比如200),静态文件没有修改返回304是好的,因为它只是回服务器校验一下是否有修改,而并没有像200那样重新请求数据。
2)
If-Unmodified-Since:
如果实体没有任何修改,那么就可以直接执行该请求, 而如果有修改,则返回一个412 Precondition Failed状态码,并且抛弃该方法对应的行为操作(GET方法除外).
Cache-Control (http1.1的常见头)
1)
public
仅体现在响应头,通知浏览器可以无条件的缓存该响应。
2)
private
仅体现在响应头,通知浏览器只针对单个用户缓存响应. 且可以具体指定某个字段.如private –“username”
3)
no-cache
a) 请求头中:告诉浏览器回去服务器取数据,并验证你的缓存(如果有的话)。
b) 响应头中:告诉浏览器,一定要回服务器校验,不管有没有缓存数据。 如果确定没有被改,可以使用缓存中 的数据
4)
no-store
告诉浏览器任何情况下都不要被缓存。
5)
max-age
a) 请求头中:强制响应浏览器,根据该值,校验缓存.即与自身的Age值,与请求时间做比较.如果超出max- age值,则强制去服务器端验证.以确保返回一个新鲜的响应.其功能本质上与传统的Expires类似,但区别在于Ex pires是根据某个特定日期值做比较.一但缓存者自身的时间不准确.则结果可能就是错误的.而max-age,显然无 此问题. Max-age的优先级也是高于Expires的.
b) 响应头中:同上
3.多线程中使用sleep和wait的区别
4.JDBC操作数据库有哪些步骤,Statement和PrepareStatement的区别?
答:
1、加载JDBC驱动程序
:
在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.lang.Class类的静态方法
forName(String className)实现。
例如:try{//加载MySql的驱动类Class.forName("com.mysql.jdbc.Driver") ;}catch(ClassNotFoundException e){System.out.println("找不到驱动程序类 ,加载驱动失败!");e.printStackTrace() ;}成功加载后,会将Driver类的实例注册到DriverManager类中。2、提供JDBC连接的URL
例如:(MySql的连接URL)
jdbc:mysql:
//localhost:3306/test?useUnicode=true&characterEncoding=gbk ;
3、创建数据库的连接
要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,
该对象就代表一个数据库的连接。
•使用DriverManager的getConnectin(String url , String username ,
String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和
密码来获得。
例如:
//连接MySql数据库,用户名和密码都是root
String url = "jdbc:mysql://localhost:3306/test" ;
String username = "root" ;
String password = "root" ;
try{
Connection con =
DriverManager.getConnection(url , username , password ) ;
}catch(SQLException se){
System.out.println("数据库连接失败!");
se.printStackTrace() ;
}
4、创建一个Statement
•要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3
种类型:
1、执行静态SQL语句。通常通过Statement实例实现。
2、执行动态SQL语句。通常通过PreparedStatement实例实现。
3、执行数据库存储过程。通常通过CallableStatement实例实现。
具体的实现方式:
Statement stmt = con.createStatement() ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
CallableStatement cstmt =
con.prepareCall("{CALL demoSp(? , ?)}") ;
5、执行SQL语句
Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate
和execute
1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句
,返回一个结果集(ResultSet)对象。
2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或
DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的
语句。
具体实现的代码:
ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;
int rows = stmt.executeUpdate("INSERT INTO ...") ;
boolean flag = stmt.execute(String sql) ;
6、处理结果
两种情况:
1、执行更新返回的是本次操作影响到的记录数。
2、执行查询返回的结果是一个ResultSet对象。
• ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些
行中数据的访问。
• 使用结果集(ResultSet)对象的访问方法获取数据:
while(rs.next()){
String name = rs.getString("name") ;
String pass = rs.getString(1) ; // 此方法比较高效
}
(列是从左到右编号的,并且从列1开始)
7、关闭JDBC对象
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声
明顺序相反:
1、关闭记录集
2、关闭声明
3、关闭连接对象
if(rs != null){ // 关闭记录集
try{
rs.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(stmt != null){ // 关闭声明
try{
stmt.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(conn != null){ // 关闭连接对象
try{
conn.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
Statement和PrepareStatement都是接口类,后面一个是预编译,至于预编译语句,比如 select * from emp where id=? 对于后面的问号是可以灵活赋值的,不是死的,它们是属于不同的两个类,Statement用于执行拼接的SQL语句,PrepareStatement可以预加载语句,把变量的值设为问号,然后再对应问号顺序赋值,这样能防止一个安全漏洞。PreparedStatement对象不仅包含了SQL语句,而且大多数情况下这个语句已经被预编译过,因而当其执行时,只需DBMS运行SQL语句,而不必先编译。当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,当然也加快了访问数据库的速度
5.分别简述以下java类之间的异同
a)ArrayList和数组
b)ArrayList和LinkedList
c)HashMap和HashTable
6.以下问题2选1
a)列出你知道的加密算法名称,简述其特征
b)列出你知道的排序算法名称,指出其中那个平均复杂度最小
7.tomcat启动时从哪些位置查找web应用,不同位置的优先级?
8.用java实现一个数组的二分查找
public class BinarySearchDemo {public static void main(String[] args) {int[] a = new int[]{1,5,7,9,11,18,23,48,69};int point = new BinarySearchDemo().binarySearch(a, 23);if(point == -1)System.out.println("在数组中未查找到数23");elseSystem.out.println("数字23是数组中第 " + (point + 1) + " 位数");}/*** 二分法查找一个整数在整型数组中的位置** 算法思路:首先得到数组a的最小值和最大值的下标,分别是:low和high,接着求出值位于数组中间那个数的下标middle* 然后再将这个middle对应的数组中的数和待查找的数num进行比较,如果相等,则表示已查找到,如果num < a[middle]* 则说明num位于a[low]和a[middle]之间,于是将a[middle - 1]设为较大值,继续求出此时对应的a[middle],* 再进行比较,其他情况可依次类推。一直到low=high,如果此时还没有在数组a中查找到,则说明该数组a中没有值num,返回-1* @param a 给定的整型数组* @param num 待查找的数 num* @return 返回整数num在数组a中的位置下标,如果未查找到则返回-1* */public int binarySearch(int[] a,int num){int low = 0;int high = a.length - 1;while(low <= high){int middle = (low + high) / 2;if(num == a[middle])return middle;else if(num < a[middle])high = middle - 1;elselow = middle + 1;}return -1;}
}
9.较小宽带下载大文件,多线程分块下载能提高速度吗?为什么?
10.在什么场景下,家里数据库索引的坏处大于好处?