1.一个‘.java’源文件中是否可以包含多个类(不是内部类)?有什么限制?
可以。必须只有一个类名与文件名相同。
2switch能否作用在byte上,.能否作用在long上,能否作用在String上?
switch(表达式)中,表达式数据类型是:整型、字符型和枚举型;
可以作用在Bytes上,不可作用域long上,java1.7以后可作用域String上。
3.说说final、finally、finalize三者的区别。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
4.Math.round(11.5)和Math.round(-11.5)分别等于多少?
Math.round(11.5)== 12
Math.round(-11.5)== -11
5.说说String、StringBuffer、StringBuilder的区别。
String是一个不可变的对象,每次对String类型的字符串进行改变时就相当于生成了一个新的String对象。
StringBuffer是可变的字符串,对StringBuffer对象进行改变时,都是改变自身而没有生成一个新的对象,经常改变字符串建议使用StringBuffer;
StringBuilder:在java1.5版本以后提供了StringBuilder类操作字符串,它等价于StringBuffer,区别在于它是线程安全的,切实单线程的,不提供同步,理论上效率更高。
三者执行效率(理论上)从高到低依次是:StringBuilder>Stringbuffer>String
6.为什么不建议记录日时使用System.out.println().
System.out.println()是在控制台输出信息,控制台的内存空间有限,不能存储所有的日志记录,而且当日志数据量非常大时查找指定的日志难度较大,在控制台输出日志还会增加服务器负担,影响其性能。
7.运行时异常和普通异常有什么区别?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
8.Tnread.sleep()和Object.wait()有什么区别?
Tnread.sleep()是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,此时系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制,但是监控状态依然保持,到时后会自动恢复,调用sleep不会释放对象锁。
Object.wait()是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,此时线程不占用任何资源,不增加时间限制,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
9.当线程进入围一个对象的一个synchronized方法之后,其他线程是否可以进入此对象的其他synchronized方法和普通方法?
(1)其他方法前是否加了synchronized关键字,如果没加,则能。
(2)如果这个方法内部调用了wait,则可以进入其他synchronized方法。
(3)如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
(4)如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。
10.如何遍历HashMap
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "11");
map.put(2, "22");
map.put(3, "33");
map.put(4, "44");
第一种:通过Map.keySet遍历key和value:
for (Integer in : map.keySet()) {
String str = map.get(in);
System.out.println(in + " " + str);
}
第二种:通过Map.entrySet使用iterator遍历key和value:
Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, String> entry = it.next();
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
第三种:通过Map.entrySet遍历key和value;
for (Map.Entry<Integer, String> entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= "
+ entry.getValue());
}
第四种:.value()方法遍历map的值
System.out.println("第四种:通过Map.values()遍历所有的value,但不能遍历key");
for (String v : map.values()) {
System.out.println("value= " + v);
}
11.Set中的元素不能重复使用,用什么方法来区分是否重复呢?是用==还是用equals?他们有什么区别?
采用equal()方法比较两个对象是否相等
equal()比较两个对象的值是否相同
== 比较的是两个对象的地址和值是否相等,简单数据类型直接比较数值如:1==2;引用类型比较两者是否是同一个对象;
12.写一个方法,计算斐波那契数列(1,1,2,3,5,8,……)第一百项的值,方法参数为第N项,返回值为第N项的(考虑程序运算效率、异常处理)。
第一百项的值:354224848179261915075
public static BigDecimal getNum(Integer n){
boolean flag=true;//声明一个标识符
List<BigDecimal> lists = new ArrayList<BigDecimal>();//声明一个集合存储斐波那契数列的值
try {
for(int i=1;i<=n;i++){
if (i<=2) {//斐波那契数列前两项值
lists.add(new BigDecimal(1));
}else{//大于两项后的值计算
lists.add((lists.get(i-3).add(lists.get(i-2))));
}
}
for (BigDecimal bigDecimal : lists) {//便利斐波那契数列
System.out.println(bigDecimal);
}
} catch (Exception e) {
flag=false;
System.err.print("出错了");
e.printStackTrace();
}
if (flag) {
return lists.get(n-1);//返回第n象的值
}else{
return new BigDecimal(0);
}
13谈谈你对java.Math.BigDecimal类的认识。
Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算.
其中 BigInteger 类是针对大整数的处理类,而 BigDecimal 类则是针对大小数的处理类.
BigDecimal 类的实现用到了 BigInteger类,不同的是 BigDecimal 加入了小数的概念.
float和Double只能用来做科学计算或者是工程计算;在商业计算中,对数字精度要求较高,必须使用 BigInteger 类和 BigDecimal 类,它支持任何精度的定点数,可以用它来精确计算货币值.
BigDecimal类创建的是对象,不能使用传统的+、-、*、/等算术运算符直接对其进行数学运算,而必须调用其对应的方法.方法的参数也必须是BigDecimal类型的对象.
构造 BigDecimal 对象常用以下方法:
BigDecimal BigDecimal(double d); //不允许使用
BigDecimal BigDecimal(String s); //常用,推荐使用
static BigDecimal valueOf(double d); //常用,推荐使用
其中,
1. double 参数的构造方法,不允许使用!!!!因为它不能精确的得到相应的值;
2. String 构造方法是完全可预知的: 写入 new BigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的0.1; 因此,通常建议优先使用 String 构造方法;
3. 静态方法 valueOf(double val) 内部实现,仍是将 double 类型转为 String 类型; 这通常是将 double(或float)转化为 BigDecimal 的首选方法;
14.Java进程间通信方式有哪些。
(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关 系 进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送 信号给进程本身;Linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
而在Java中我们实现多线程间通信则主要采用"共享变量"和"管道流"这两种方法
方法一 通过访问共享变量的方式(注:需要处理同步问题)
方法二 通过管道流
其中方法一有两种实现方法,即
方法一a)通过内部类实现线程的共享变量
15.Css规则Style=“padding:0 0 3px 3px”设置的元素内边距分别是多少。
上内边距:0px 右内边距0px 下内边距3px 左内边距3px
16.说出HTTP请求的GET和POST方式的区别。
Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求
Get是获取信息,而不是修改信息,类似数据库查询功能一样,数据不会被修改
Get请求的参数会跟在url后进行传递,请求的数据会附在URL之后,以?分割URL和传输数据,参数之间以&相连,%XX中的XX为该符号以16进制表示的ASCII,如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密。
Get传输的数据有大小限制,因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了,不同的浏览器对URL的长度的限制是不同的。
GET请求的数据会被浏览器缓存起来,用户名和密码将明文出现在URL上,其他人可以查到历史浏览记录,数据不太安全。在服务器端,用Request.QueryString来获取Get方式提交来的数据
Post请求则作为http消息的实际内容发送给web服务器,数据放置在HTML Header内提交,Post没有限制提交的数据。Post比Get安全,当数据是中文或者不敏感的数据,则用get,因为使用get,参数会显示在地址,对于敏感数据和不是中文字符的数据,则用post
POST表示可能修改变服务器上的资源的请求,在服务器端,用Post方式提交的数据只能用Request.Form来获取
17.Servlet的forward和redirect的区别。
forward:转发---是服务器端行为,携带请求数据,客户端的Url显示不改变,且客户端只发送请求了一次
redirect:重定向----是客户端行为,不携带请求数据,客户端的Url显示改变,且客户端至少发送请求了两次
18.写一段JDBC查询oracle数据的代码。
package com.test.dbtest;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestO_procedure01 {
public static void main(String[] args) {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:Oracle:thin:@localhost:1521:orcl";
PreparedStatement stmt = null;
ResultSet res = null;
Connection conn = null;
CallableStatement proc = null;
String sql = " select t.tid, t.tname,t.tage from teacher t where t.name=upper('AT')";
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, "abc123", "abc123");
stmt = conn.prepareStatement(sql);
res = stmt.executeQuery();
while(res.hasNext())
{
String tid = res.getInt("tid");
String tname = res.getString("tname");
String tage= res.getInt("tage");
System.out.println(tid+" "+tname+" "+taget);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
19.JDBC中PreparedStatement相比Statement的好处。
(1)极大提高了安全性能,可以防止sql注入
(2)代码的可读性和可维护性相比Statement要好.
(3)有预编译功能,相同操作批量数据效率较高
因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行
20.选择自己熟悉的数据库。写出下列SQL语句:
建立表library;
mysql: create table library(
lid INT(6) PRIMARY KEY AUTO_INCREMENT,
lname CHAR(12);
lsum INT(8)
)
oracle:create table library
( lid number(6) not null,
lname varchar2(12) not null,
ldate date,
lusersex varchar2(2)
);
插入多个数据
insert into library (lid,lname,ldate,lusersex) values (1200,’小小’,’女’,to_date(‘2016-08-08’,’yyyy-mm-dd’));
添加主键约束
alter table library constraint pk_library_lid primary key(lid);
添加唯一约束
alter table library add constraint uk_library_lname unique(lname);
添加检查约束
alter table library add constraint ck_library_lusersex check(lusersex in
(‘男’,’女’));
添加外键约束:
alter table library fk_library_lid foreign key(lid) references user (ulid);