java面试题总结

[color=red]其实要提高自己的技术水平,做到3点:
1. 多看书,特别是理论方面的;
2. 看人家写的代码,自己想想为什么人家这么写;
3. 不懂的先上网查,没查到再问同事
[/color]

[size=medium][color=red]整合,来源不限。[/color][/size]
[color=red](1)web页面的farward 以及 redirect 有何区别??[/color]
Forward是服务器内部重定向,服务器接到接到请求后访问url获取响应然后发给浏览器,浏览器不知服务器发送到内容是从哪里来的,所以地址栏不会变化
Redirect是服务器接收客户端请求后,发个状态码给浏览器,浏览器再次请求 url,此时地址栏会变化
转发会可以保存存在request中的数据,而重定向会丢失这些东西
SERVLET API中forward() 与redirect()的区别?
答:前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用
sendRedirect()方法。
[color=red](2)军翔的道讯erp系统设计的是C/S还是B/S模式?-->查询C/S模式和B/S模式的区别?[/color]
C/S结构模式,(所有的桌面应用程序开发都是cs模式)
比较两种模式的区别:
cs模式是client和server,将应用和服务分离系统具有稳定和灵活性,cs模式配备的是点对点的结构模式适用于局域网,有可靠的安全性
bs模式是brower和server,是指在TCP/IP的支持下,以HTTP为传输协议,客户端通过Browser访问Web服务器以及与之相连的后台数据库的技术及体系结构。系统开发和维护升级方便(想想为什么?),用户通过通用的浏览器进行访问,开放性好,使用方便。
[color=red](3)一个网站有很大的访问量,有什么办法来解决?[/color]
主要从架构层面解决:1,使用服务器集群,如tomcat集群;2,使用缓存,如memcache;3,使用数据库集群,如mysql集群
[color=red](4)如何进行数据库优化?[/color]
1、 硬件调整性能
最有可能影响性能的是磁盘和网络吞吐量,解决办法
扩大虚拟内存,并保证有足够可以扩充的空间;把数据库服务器上的不必要服务关闭掉
把数据库服务器和主域服务器分开
把SQL数据库服务器的吞吐量调为最大
在具有一个以上处理器的机器上运行SQL
2、 调整数据库
若对该表的查询频率比较高,则建立索引;建立索引时,想尽对该表的所有查询搜索操作, 按照where选择条件建立索引,尽量为整型键建立为有且只有一个簇集索引,数据在物理上按顺序在数据页上,缩短查找范围,为在查询经常使用的全部列建立非簇集索引,能最大地覆盖查询;但是索引不可太多,执行UPDATE DELETE INSERT语句需要用于维护这些索引的开销量急剧增加;避免在索引中有太多的索引键;避免使用大型数据类型的列为索引;保证每个索引键值有少数行。
3、 使用存储过程
应用程序的实现过程中,能够采用存储过程实现的对数据库的操作尽量通过存储过程来实现,因为存储过程是存放在数据库服务器上的一次性被设计、编码、测试,并被再次使用,需要执行该任务的应用可以简单地执行存储过程,并且只返回结果集或者数值,这样不仅可以使程序模块化,同时提高响应速度,减少网络流量,并且通过输入参数接受输入,使得在应用中完成逻辑的一致性实现。
4、 应用程序结构和算法
建立查询条件索引仅仅是提高速度的前提条件,响应速度的提高还依赖于对索引的使用。因为人们在使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,特别是对数据量不是特别大的数据库操作时,是否建立索引和使用索引的好坏对程序的响应速度并不大,因此程序员在书写程序时就忽略了不同的实现方法之间可能存在的性能差异,这种性能差异在数据量特别大时或者大型的或是复杂的数据库环境中(如联机事务处理OLTP或决策支持系统DSS)中表现得尤为明显。在工作实践中发现,不良的SQL往往来自于不恰当的索引设计、不充份的连接条件和不可优化的where子句。在对它们进行适当的优化后,其运行速度有了明显地提高!
因此在书写应用程序的SQL的 where子句时,注意以下几种情况:
1、避免使用不兼容的数据类型。例如float和int、char和varchar、binary和varbinary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如:
SELECT name FROM employee WHERE salary > 60000
在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000是个整型数。我们应当在编程时将整型转化成为钱币型,而不要等到运行时转化。
2、避免对搜索参数使用其它数学操作符,如要将
SELECT name FROM employee WHERE SUBSTRING(id, 1, 1) = 'B'
SELECT name FROM emplyee WHERE salary * 12 > 30000
写成为:
SELECT name FROM employee WHERE id like ‘B%'
SELECT name FROM emplyee WHERE salary > 3000
3、、避免使用!=或<>等这样的操作符,因为这会使系统无法使用索引,而只能直接搜索表中的数据。例如:
SELECT id FROM employeeWHERE id != 'B%'
优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。
4、在应用程序中,保证在实现功能的基础上,尽量减少对数据库的访问次数;通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;能够分开的操作尽量分开处理,提高每次的响应速度;在数据窗口使用SQL时,尽量把使用的索引放在选择的首列;算法的结构尽量简单;在查询时,不要过多地使用通配符如select *语句;尽量不要在应用中使用数据库游标,游标是非常有用的工具,但比使用常规的、面向集的SQL语句需要更大的开销;按照特定顺序提取数据的查找。
上面我们提到的是一些基本的提高查询速度的注意事项,但是在更多的情况下,程序员往往需要反复试验比较不同的语句以得到最佳方案。此外更为重要的是需要数据库管理员在数据库的服务器一端调整数据库管理系统的参数,以得到更快的响应性能。
[color=red](5)在网页上打印一个三角形("*")[/color]

package com.xiangxm.javatest.demo;

/*
*<p>
*用*打印一个三角形
*</p>
*@author xiangxm
*version 1.0
*2013-4-3
*
*
*/
public class TriangleDemo {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

int n = 9;
for ( int i = 1; i < n; i++) {
for ( int j = 1; j <= i; j++) {
System. out.print( "*");
}
System. out.println( " ");
}
}

}

*
**
***
****
*****
******
*******
********

 public static void main(String[] args) {
for ( int i = 1; i <= 10; i++) {
for ( int j = 1; j <= 10 - i; j++) // 打印每行的空格
{
System. out.print( " ");
}
for ( int j = 1; j <= 2 * i - 1; j++) // 打印每行的*
{
System. out.print( "*");
}
System. out.println();
}
}

*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
[color=red](6)编程序实现两个排序算法[/color]
 package com.xiangxm.javatest.exam;
/*
*
* 选择排序
*/
class Sort {
private long[] a;
private int nElement;

public Sort( long[] array) {
this. a = array;
}

public static void main(String[] args) {
long[] array = new long[] { 5, 3, 1, 7, 9, 2, 0 };
Sort b = new Sort(array);
b.selectSort();
System. out.println(b);
}

// 选择排序
public void selectSort() {
int out, in, low;
int step = 0;
for (out = 0; out < a. length; out++) {
low = out; // low 记录当前最小对象的位置。初始化指向起始的比较对象,

// 同冒泡一样,遍历比较数组中所有的对象。并且记录最小当前
// 最小对象的位置。
for (in = out + 1; in < a. length; in++) {
if ( a[low] > a[in]) {
low = in;
}
}
// 将当前对象对象置换至当前排序中对应的位置。
if (low != out) { //表示数组中还是有比他更小的数了。、
long temp = a[out];
a[out] = a[low];
a[low] = temp;
step++;
}
}
System. out.println( "step = " + step);
}

public String toString() {
StringBuilder b = new StringBuilder();
for ( long l : a) {
b.append(l);
b.append( ",");
}
return b.toString();
}
}
public class InsertSort {
/**
* 插入排序算法实现
* @author Jason
* @param arr
* @return
*/
public static int[] insertSort( int[] arr) {
int searchCount = 0;
for ( int out = 1; out < arr. length; out++) {
outPrint(arr);
if (arr[out]>arr[out-1]) {
continue;
}
//普通查找算法
/*for (int inn = 0; inn < out; inn++) {
searchCount++;
if ( arr[out]<arr[inn]) {
move( arr,out,inn);
break;
}else {
continue;
}
}*/
//使用二分查找算法找到要插入的位置
int start = 0;
int end = out - 1;
while (start <= end) {
searchCount++;
int searchIndex = (start + end) / 2;
if (arr[out] > arr[searchIndex]) {
start = searchIndex + 1;
} else if (arr[out] < arr[searchIndex]) {
if (searchIndex == 0
|| (searchIndex != 0 && arr[out] > arr[searchIndex - 1])) {
move(arr, out, searchIndex);
break;
} else {
end = searchIndex - 1;
continue;
}
} else {
move(arr, out, searchIndex);
break;
}
}
}
check(arr);
System. out.println( "Search Count:" + searchCount);
return arr;
}
/**
* 移动数据
*/
private static void move(int[] arr, int out, int inn) {
int changeTemp = arr[out];
for ( int i = out; i > inn; i--) {
arr[i] = arr[i - 1];
}
arr[inn] = changeTemp;
}
/**
* 输出
*/
private static void outPrint( int[] arr) {
System. out.println();
for ( int i = 0; i < arr. length; i++) {
System. out.print(arr[i] + "|");
}
}
/**
* 结果检查
*/
private static boolean check( int[] arr) {
System. out.println();
for ( int i = 1; i < arr. length; i++) {
if (arr[i] < arr[i - 1]) {
System. out.println( "Sort Error!");
return false;
}
}
System. out.println( "Sort Success!");
return true;
}
/**
* 测试方法
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Random ran = new Random();
int[] arr = new int[5];
for ( int i = 0; i < arr. length; i++) {
arr[i]=ran.nextInt(30);
}
System. out.println( "Befor sort:");
for ( int i = 0; i < arr. length; i++) {
System. out.print(arr[i]+ "|");
}
arr = InsertSort. insertSort(arr);
System. out.println( "After sort:");
for ( int i = 0; i < arr. length; i++) {
System. out.print(arr[i]+ "|");
}

}
}

[color=red](7)ajax、jequery、json
(8)对象的概念以及表现(封装,继承,多态)
(9)session和cookie的区别以及浏览器禁用了session和cookie是否还可以正常使用?(保存位置;保存的内容,路径)[/color]
1、session保存在服务器,客户端不知道其中的信息;cookie保存在客户端,服务器能够知道其中的信息。
2、session中保存的是对象,cookie中保存的是字符串。
3、session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到。而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的。
4、session需要借助cookie才能正常<nobr οncοntextmenu="return false;" οnmοusemοve="kwM(3);" id="key3" οnmοuseοver="kwE(event,3, this);" style="COLOR: #6600ff; BORDER-BOTTOM: 0px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" οnclick="return kwC();" οnmοuseοut="kwL(event, this);" target="_blank">工作</nobr>。如果客户端完全禁止cookie,session将失效。
http是无状态的协议,客户每次读取web页面时,服务器都打开新的会话,而且服务器也不会自动维护客户的上下文信息,那么要怎么才能实现网上商店中的购物车呢,session就是一种保存上下文信息的机制,它是针对每一个用户的,变量的值保存在服务器端,通过SessionID来区分不同的客户,session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie,我们叫做session cookie,以区别persistent cookies,也就是我们通常所说的cookie,注意session cookie是存储于浏览器内存中的,并不是写到硬盘上的,这也就是我们刚才看到的JSESSIONID,我们通常情是看不到JSESSIONID的,但是当我们把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,我们就可以在地址栏看到sessionid=KWJHUG6JJM65HS2K6之类的字符串。
明白了原理,我们就可以很容易的分辨出persistent cookies和session cookie的区别了,网上那些关于两者安全性的讨论也就一目了然了,session cookie针对某一次会话而言,会话结束session cookie也就随着消失了,而persistent cookie只是存在于客户端硬盘上的一段文本(通常是加密的),而且可能会遭到cookie欺骗以及针对cookie的跨站脚本攻击,自然不如session cookie安全了。
通常session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的sessionid,这样我们信息共享的目的就达不到了,此时我们可以先把sessionid保存在persistent cookie中,然后在新窗口中读出来,就可以得到上一个窗口SessionID了,这样通过session cookie和persistent cookie的结合我们就实现了跨窗口的session tracking(会话跟踪)。
在一些web开发的书中,往往只是简单的把Session和cookie作为两种并列的http传送信息的方式,session cookies位于服务器端,persistent cookie位于客户端,可是session又是以cookie为基础的,明白的两者之间的联系和区别,我们就不难选择合适的技术来开发web service了。
(10)html页面实现登录功能
(11)sql插入删除修改某一列数据,查询发帖人数最多的前10个人。
(12)编写一个函数实现列出某一文件夹下的所有子文件--->本题衍生:java对文件的操作。

package com.xiangxm.javatest.answer;

import java.io.File;

/*
*<p>
*遍历目录下的所有文件,运用了递归的方式。
*</p>
*@author xiangxm
*version 1.0
*2013-4-2
*
*
*/
public class FetchFiles {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

File[] files = File. listRoots();
for (File file : files) {
fetchFiles(file.getPath());
}
}

public static void fetchFiles(String path) {

File file = new File(path);

File[] roots = file.listFiles();

if (roots != null) {
for (File file1 : roots) {

System. out.println(file1.getPath());

if (file1.isDirectory()) {

File[] root = file1.listFiles();

if (root != null) {
for (File file2 : root) {
System. out.println(file2.getPath());

if (file2.isDirectory()) {

fetchFiles(file2.getPath());
}

}
}
}

}

}
}
}


package com.xiangxm.javatest.answer;

import java.io.File;

/*
* 移动指定目录下的文件
*
*/

public class FileDemo_06 {
// 移动某个指定的文件,但移动成功后不会覆盖已存在的目标文件
public static boolean moveA_File(String sourceFileName,
String targetFileName) {
return FileDemo_06. moveA_File(sourceFileName, targetFileName, false);
}

// 移动某个指定的文件,但移动成功后可以根据isOverlay的值来决定是否覆盖已存在的目标文件
public static boolean moveA_File(String sourceFileName,
String targetFileName, boolean isOverlay) {
// 判断原文件是否存在
File sourceFile = new File(sourceFileName);
if (!sourceFile.exists()) {
System. out.println( "移动文件失败:原文件" + sourceFileName + "不存在!" );
return false;
} else if (!sourceFile.isFile()) {
System. out.println( "移动文件失败:" + sourceFileName + "不是一个文件!" );
return false;
}
File targetFile = new File(targetFileName);
if (targetFile.exists()) { // 判断目标文件是否存在
if (isOverlay) { // 如果目标文件存在,是否允许覆盖目标文件
// 删除已存在的目标文件,无论目标文件是目录还是单个文件
System. out.println( "该文件已存在,准备删除它!" );
if (!FileDemo_05.deleteAnyone(targetFileName)) {
System. out.println( "文件移动失败,删除文件" + targetFileName + "失败!" );
return false;
}
} else {
System. out.println( "文件移动失败,文件" + targetFileName + "已存在!" );
return false;
}
} else {
if (!targetFile.getParentFile().exists()) {
// 如果目标文件所在的目录不存在,则创建目录
System. out.println( "该文件所在目录不存在,正在创建!" );
if (!targetFile.getParentFile().mkdirs()) {
System. out.println( "移动文件失败,创建文件所在的目录失败!" );
return false;
}
}
}
// 移动原文件至目标文件
if (sourceFile.renameTo(targetFile)) {
System. out.println( "移动文件" + sourceFileName + "到" + targetFileName
+ "成功!");
return true;
} else {
System. out.println( "移动文件" + sourceFileName + "到" + targetFileName
+ "失败!");
return true;
}
}

public static boolean moveDir(String sourceDirName, String targetDirName) {
// 默认为不覆盖目标文件
return FileDemo_06. moveDir(sourceDirName, targetDirName, false);
}

// 移动某个指定的目录,但移动成功后可以根据isOverlay的值来决定是否覆盖当前已存在的目标目录
public static boolean moveDir(String sourceDirName, String targetDirName,
boolean isOverlay) {
// 判断原目录是否存在
File sourceDir = new File(sourceDirName);
if (!sourceDir.exists()) {
System. out.println( "移动目录失败,原始目录" + sourceDirName + "不存在!" );
return false;
} else if (!sourceDir.isDirectory()) {
System. out.println( "移动目录失败," + sourceDirName + "不是一个目录!" );
return false;
}
// 如果目标文件夹名不以文件分隔符结尾,自动添加文件分隔符
if (!targetDirName.endsWith(File. separator)) {
targetDirName = targetDirName + File. separator;
}
File targetDir = new File(targetDirName);
// 如果目标文件夹存在,
if (targetDir.exists()) {
if (isOverlay) {
// 允许覆盖则删除已存在的目标目录
System. out.println( "该目录已存在,准备删除它!" );
if (!FileDemo_05.deleteAnyone(targetDirName)) {
System. out.println( "移动目录失败:删除目录" + targetDirName + "失败!" );
}
} else {
System. out.println( "移动目录失败:该目录" + targetDirName + "已存在!" );
return false;
}
} else {
// 创建目标目录
System. out.println( "该目录不存在,正在创建!" );
if (!targetDir.mkdirs()) {
System. out.println( "移动目录失败:创建该目录失败!" );
return false;
}
}
boolean flag = true;
// 移动原目录下的文件和子目录到目标目录下
File[] files = sourceDir.listFiles();
for ( int i = 0; i < files. length; i++) {
// 移动子文件
if (files[i].isFile()) {
flag = FileDemo_06.moveA_File(files[i].getAbsolutePath(),
targetDirName + files[i].getName(), isOverlay);
if (!flag) {
break;
}
}
// 移动子目录
else if (files[i].isDirectory()) {
flag = FileDemo_06.moveDir(files[i].getAbsolutePath(),
targetDirName + files[i].getName(), isOverlay);
if (!flag) {
break;
}
}
}
if (!flag) {
System. out.println( "目录" + sourceDirName + "移动到" + targetDirName
+ "失败!");
return false;
}
// 删除原目录
if (FileDemo_05. deleteDir(sourceDirName)) {
System. out.println( "目录" + sourceDirName + "移动到" + targetDirName
+ "成功!");
return true;
} else {
System. out.println( "目录" + sourceDirName + "移动到" + targetDirName
+ "失败!");
return false;
}
}

public static void main(String[] args) {
// 移动文件,如果目标文件存在,则替换
System. out.println( "调用moveA_File方法的结果如下:" );
String sourceFileName = "D:\\temp\\keytoolcmd.txt";
String targetFileName = "D:\\test\\temp\\keytoolcmd.txt." ;
FileDemo_06. moveA_File(sourceFileName, targetFileName, true);
// 移动目录,如果目标目录存在,则不覆盖
System. out.println( "\n调用moveDir方法的结果如下:" );
String sourceDirName = "D:\\temp\\aa";
String targetDirName = "F:\\abc";
FileDemo_06. moveDir(sourceDirName, targetDirName);
}
}


package com.xiangxm.javatest.answer;

import java.io.File;

/*
* 删除指定目录下的文件
*
*/
public class FileDemo_05 {
// 判断删除指定的文件或文件夹是否成功,成功则返回true否则返回false
public static boolean deleteAnyone(String fileName) {
File file = new File(fileName);
if (!file.exists()) {
System. out.println( "文件删除失败:" + fileName + "文件不存在!" );
return false;
} else {
if (file.isFile()) {
return FileDemo_05. deleteFiles(fileName);
} else {
return FileDemo_05. deleteDir(fileName);
}
}
}

// 判断删除指定的文件是否成功,成功则返回true否则返回false
public static boolean deleteFiles(String fileName) {
File file = new File(fileName);
// 如果文件路径对应的文件存在,并且是一个文件,则直接删除。
if (file.exists() && file.isFile()) {
if (file.delete()) {
System. out.println( "文件:" + fileName + "删除成功!" );
return true;
} else {
System. out.println( "文件" + fileName + "删除失败!" );
return false;
}
} else {
System. out.println( "文件删除失败:" + fileName + "文件不存在!" );
return false;
}
}

// 判断删除指定的目录(文件夹)以及目录下的文件是否成功,成功则返回true否则返回false
public static boolean deleteDir(String dir) {
// 如果dir 不以文件分隔符结尾,自动添加文件分隔符。
if (!dir.endsWith(File. separator)) {
dir = dir + File. separator;
}
File dirFile = new File(dir);
// 如果dir 表示的文件不存在,或者不是一个文件夹,则退出
if (!dirFile.exists() || (!dirFile.isDirectory())) {
System. out.println( "目录删除失败:" + dir + "目录不存在!" );
return false;
}
boolean flag = true;
// 删除指定目录下所有文件(包括子目录)
File[] files = dirFile.listFiles();
for ( int i = 0; i < files. length; i++) {
// 删除文件
if (files[i].isFile()) {
flag = FileDemo_05.deleteFiles(files[i].getAbsolutePath());
if (!flag) {
break;
}
}
// 删除子目录
else if (files[i].isDirectory()) {
flag = FileDemo_05.deleteDir(files[i].getAbsolutePath());
if (!flag) {
break;
}
}
}
if (!flag) {
System. out.println( "删除目录失败!" );
return false;
}
// 删除当前目录
if (dirFile.delete()) {
System. out.println( "目录:" + dir + "删除成功!" );
return true;
} else {
return false;
}
}

public static void main(String[] args) {
// 删除文件
System. out.println( "调用deleteFiles方法的结果如下:" );
String file = "D:\\temp\\aa\\bb\\ccFile.txt";
FileDemo_05. deleteFiles(file);
System. out.println();
// 删除目录
System. out.println( "调用deleteDir方法的结果如下:" );
String dir = "D:\\temp\\key";
FileDemo_05. deleteDir(dir);
System. out.println();
// 删除文件或目录
System. out.println( "调用deleteAnyone方法的结果如下:" );
dir = "D:\\temp\\read";
FileDemo_05. deleteAnyone(dir);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值