a[j]=a[j]+a[j-1];
a[j-1]=a[j]-a[j-1];
a[j]=a[j]-a[j-1];
}
}
}
}
- 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。
【参考答案】
最终的程序代码如下:
public class ThreadTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new ThreadTest().init();
}
public void init()
{
final Business business = new Business();
new Thread(
new Runnable()
{
public void run() {
for(int i=0;i<50;i++)
{
business.SubThread(i);
}
}
}
).start();
for(int i=0;i<50;i++)
{
business.MainThread(i);
}
}
private class Business
{
boolean bShouldSub = true;//这里相当于定义了控制该谁执行的一个信号灯
public synchronized void MainThread(int i)
{
if(bShouldSub)
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int j=0;j<5;j++)
{
System.out.println(Thread.currentThread().getName() + ":i=" + i +",j=" + j);
}
bShouldSub = true;
this.notify();
}
public synchronized void SubThread(int i)
{
if(!bShouldSub)
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int j=0;j<10;j++)
{
System.out.println(Thread.currentThread().getName() + ":i=" + i +",j=" + j);
}
bShouldSub = false;
this.notify();
}
}
}
备注:不可能一上来就写出上面的完整代码,最初写出来的代码如下,问题在于两个线程的代码要参照同一个变量,即这两个线程的代码要共享数据,所以,把这两个线程的执行代码搬到同一个类中去:
package com.huawei.interview.lym;
public class ThreadTest {
private static boolean bShouldMain = false;
public static void main(String[] args) {
// TODO Auto-generated method stub
/*new Thread(){
public void run()
{
for(int i=0;i<50;i++)
{
for(int j=0;j<10;j++)
{
System.out.println("i=" + i + ",j=" + j);
}
}
}
}.start();*/
//final String str = new String("");
new Thread(
new Runnable()
{
public void run()
{
for(int i=0;i<50;i++)
{
synchronized (ThreadTest.class) {
if(bShouldMain)
{
try {
ThreadTest.class.wait();}
catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int j=0;j<10;j++)
{
System.out.println(
Thread.currentThread().getName() +
"i=" + i + ",j=" + j);
}
bShouldMain = true;
ThreadTest.class.notify();
}
}
}
}
).start();
for(int i=0;i<50;i++)
{
synchronized (ThreadTest.class) {
if(!bShouldMain)
{
try {
ThreadTest.class.wait();}
catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int j=0;j<5;j++)
{
System.out.println(
Thread.currentThread().getName() +
"i=" + i + ",j=" + j);
}
bShouldMain = false;
ThreadTest.class.notify();
}
}
}
}
下面使用jdk5中的并发库来实现的:
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
public class ThreadTest
{
private static Lock lock = new ReentrantLock();
private static Condition subThreadCondition = lock.newCondition();
private static boolean bBhouldSubThread = false;
public static void main(String [] args)
{
ExecutorService threadPool = Executors.newFixedThreadPool(3);
threadPool.execute(new Runnable(){
public void run()
{
for(int i=0;i<50;i++)
{
lock.lock();
try
{
if(!bBhouldSubThread)
subThreadCondition.await();
for(int j=0;j<10;j++)
{
System.out.println(Thread.currentThread().getName() + ",j=" + j);
}
bBhouldSubThread = false;
subThreadCondition.signal();
}catch(Exception e)
{
}
finally
{
lock.unlock();
}
}
}
});
threadPool.shutdown();
for(int i=0;i<50;i++)
{
lock.lock();
try
{
if(bBhouldSubThread)
subThreadCondition.await();
for(int j=0;j<10;j++)
{
System.out.println(Thread.currentThread().getName() + ",j=" + j);
}
bBhouldSubThread = true;
subThreadCondition.signal();
}catch(Exception e)
{
}
finally
{
lock.unlock();
}
}
}
- 写一个程序,把一个文件的数组按对角线做对称变换,并输出!
【参考答案】
一个正方形里面全数字,写一个程序,成对角线转变! 我做的这个是3行3列的对角互换,也许转换规则不一样
public class testMain {
public static void main(String[] args) {
int a[][]=new int[3][3];
int c=1;
//初始化数据
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
a[i][j]=c++;
}
}
System.out.println("转换之前:");
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
System.out.print("a["+i+"]["+j+"]="+a[i][j]+" ");
}
System.out.println("\n");
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if((i+1<3&&j+1<3)&&i==j&&i!=0&&i!=3-i){
int temp=a[i-1][j-1];
a[i-1][j-1]=a[i+1][j+1];
a[i+1][j+1]=temp;
temp=a[i-1][j+1];
a[i-1][j+1]=a[i+1][j-1];
a[i+1][j-1]=temp;
}
}
}
System.out.println("转换之后:");
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
System.out
print("a["+i+"]["+j+"]="+a[i][j]+" ");
}
System.out.println("\n");
}
}
}
- 写一个方法,传入一个int 型的数字,把它的四个字节码取出来,并且把它按大小顺序通过控制台输出?
【参考答案】
public static void main(String[] args) {
int num = -800000000;
String str = Integer.toBinaryString(num); //获得num 的二进制
if(num>=0) { //如果输入的数为正数,位数可能不足32位,要补0;负数肯定是32位
if(str.length()<32) { //二进制不足32位,就在前面补0
int n0 = 32-str.length(); //看差几个0
String temp = "";
for(int i=0;i temp = temp + "0"; //拼0
}
str = temp + str;
}
}
String s1 = str.substring(0, 8);
String s2 = str.substring(8, 16);
String s3 = str.substring(16, 24);
String s4 = str.substring(24, 32);
System.out.println(str);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
int n1=Integer.parseInt(s1,2);//以二进制把字符串解析为 10进制的数
int n2=Integer.parseInt(s2,2);
int n3=Integer.parseInt(s3,2);
int n4=Integer.parseInt(s4,2);
System.out.println(n1);
System.out.println(n2);
System.out.println(n3);
System.out.println(n4); //整数大小自己比较吧
}
【分析】
- 设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
【参考答案】
以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。
public class ThreadTest1
{
private int j;
public static void main(String args[]){
ThreadTest1 tt=new ThreadTest1();
Inc inc=tt.new Inc();
Dec dec=tt.new Dec();
for(int i=0;i<2;i++){
Thread t=new Thread(inc);
t.start();
t=new Thread(dec);
t.start();
}
}
private synchronized void inc(){
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);
}
private synchronized void dec(){
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
class Inc implements Runnable{
public void run(){
for(int i=0;i<100;i++){
inc();
}
}
}
class Dec implements Runnable{
public void run(){
for(int i=0;i<100;i++){
dec();
}
}
}
}
----------随手再写的一个-------------
class A
{
JManger j =new JManager();
main()
{
new A().call();
}
void call
{
for(int i=0;i<2;i++)
{
new Thread(
new Runnable(){ public void run(){while(true){j.accumulate()}}}
).start();
new Thread(new Runnable(){ public void run(){while(true){j.sub()}}}).start();
}
}
}
class JManager
{
private j = 0;
public synchronized void subtract()
{
j--
}
public synchronized void accumulate()
{
j++;
}
}
- 十六进制的216转换十进制是多少?
216是16进制,转10进制:
=2*16^2+1*16^1+6*16^0
=512+16+6
=536
以下函数htoi函数的功能是将一个十六进制数字的字符串,转换成它等价的十进制整数值。
Public int htoi(char s[])
{
Int i , n ;
N=0;
For(i=0 , s[i]<’\0’;i++)
{
If(s[i]>=0&&s[i]<=9) n=_______
If(s[i]>=’a’&&s[i]<=’f’) n=_________
If(s[i]>=’A’&&s[i]<=’F’) n=_________
}
Return (n);
}
- 如何把一段逗号分割的字符串转换成一个数组?
【参考答案】
可以说说我的思路:
- 用正则表达式,代码大概为:String [] result = orgStr.split(“,”);
- 用StingTokenizer ,代码为:
StringTokenizer tokener = StringTokenizer(orgStr,”,”);
String [] result = new String[tokener .countTokens()];
Int i=0;
while(tokener.hasNext(){result[i++]=toker.nextToken();}
- 编写一个函数将一个十六进制数的字符串参数转换成整数返回。
【参考答案】
String str = “13abf”;
int len = str.length;
int sum = 0;
for(int i=0;i
char c = str.charAt(len-1-i);
int n = Character.digit(c,16);
sum += n * (1<<(4*i));
}
其实,也可以用Integer.parseInt(str,16),但面试官很可能是想考我们的编码基本功。
- 读取一个文件在控制台打印出来
【参考答案】
File file = new File("E:\\JRadioButtonDemo.java");
long file_length= file.length();
try {
//输入流
FileInputStream input = new FileInputStream(file);
byte b_data [] = new byte[(int)file_length];
input.read(b_data);
System.out.println(new String(b_data));
input.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
- 递归实现1,1,2,3,5,8,….第30个数是多少?【上海菲耐德】
【参考答案】
public static int Foo(int i)
{
if (i <= 0)
return 0;
else if(i > 0 && i <= 2)
return 1;
else return Foo(i -1) + Foo(i - 2);
}
int i=Foo(30);
System.out.println(i);
- 求一个字符串中第一个无重复的字符
public static void getUniqueString(String str){
boolean bool = true;
for(int i=0;i
String s1 = str.substring(i, i+1);
if(str.indexOf(s1, i+1)==-1){
System.out.println(s1);
bool = false;
}
}
}
- 写一个递归函数,输入一个整数,反序输出这个整数
// 写一个递归函数,输入一个整数,反序输出这个整数
public static void printOut(int n) {
System.out.print(n % 10);
if (n >= 10){
printOut(n / 10);
}
}
- 有一个数据文件:123 34 17 651234 345....这些数据都是随机产生的,编写程序读出该文件.并将其以从大到小的顺序输出到另一个文件中.
public void readtext(){
File file = new File("D:\test.txt");
List list= new ArrayList();
try {
BufferedReader br=new BufferedReader(new FileReader(file));
String data = "";
String line = null;
while ( (line = br.readLine()) != null) {
data = data.concat(line);
}
StringTokenizer stoken = new StringTokenizer(data, " ");
while (stoken.hasMoreTokens()) {
int i = Integer.parseInt(stoken.nextToken());
list.add(i);
}
} catch(Exception ex) {}
String[] str = new String[list.size()];
for(int i=0;i
str[i]=list.get(i);
}
Object iTemp= null;
for(int i=1;i
for(int j=list.size()-1;j>=i;j--) {
if(str[j]>str[j-1]) {
iTemp = str[j-1];
str[j-1] = str[j];
str[j] = iTemp;
}
}
String result = "";
for(int i=0;i
result +=str[i]+" ";
}
//将result写入另外一个文件即可。
}
- 从一到十九共十九个数,打印出利用这十九个整数任意多个相加等于20所以可能性,每个数字在同一个算式中只出现一次.
public void test(){
Integer[] a = new Integer[19];
for(int i=1;i<20;i++){
a[i-1]=i;
}
for(int i=0;i<18;i++){
for(int j=18-i;j<18;j++)
if(a[i]+a[j]==20)
System.out.println(a[i]+"+"+a[i+1]+"="+20);
}
}
- 一个字符串中可能存在A-Z的全角字符,写一个方法把里面的全角字符转变成半角字符?
答:采用建立字典表进行查找转换
public static String translate(String s){
String qj = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String bj = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
StringBuffer sb = new StringBuffer();
for(int i=0;i char c = s.charAt(i);
int pos = qj.indexOf(c);
if(pos>=0){
System.out.println(c + "," + pos);
sb.append(bj.charAt(pos));
}else{
sb.append(c);
}
}
return sb.toString();
}
- Stack堆栈,实现进栈、出栈。【云巢动脉面试题】
package t1;
public class mystack {
private Object[] data;
private int top=-1;
private int size;
public mystack()
{
data=new Object[5];
size=5;
}
public mystack(int size)
{
data=new Object[size];
this.size=size;
}
public void push(Object obj)
{
if(this.isfull())
{
return ;
}
top++;
data[top]=obj;
}
public Object pop() {
if(this.isempty())
{
return null;
}
Object obj=data[top];
top--;
return obj ;
}
public boolean isfull()
{
if(top==data.length)
{
return true;
}
else
{
return false;
}
}
public boolean isempty()
{
if(top==-1)
{
return true;
}
else
{
return false;
}
}
}
- 定义两个变量a和b,不使用第三个变量,使两个值交换
public class testMain {
public void test(int a,int b){
System.out.println("交换前a = "+a);
System.out.println("交换前b = "+b);
a=a+b;
b=a-b;
a=a-b;
System.out.println("交换后a = " +a);
System.out.print("交换后b = "+b);
}
public static void main(String args[]){
new testMain().test(10,13);
}
}
- 针对一个分期付款,总期为1年,给定分期金额,期数和开始还款时间,计算出各期还款日期。
package demo;
import java.util.Calendar;
import java.util.Date;
public class TestDemo {
// 分期付款,总期为1年,给定分期金额,期数和开始还款时间
// 计算出各期还款日期
public void huankuan(double amount,int num,Date start){
int period = 365/num; // 一年中分期间隔天数
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, start.getYear()+1900);
cal.set(Calendar.MONTH, start.getMonth());
cal.set(Calendar.DATE, start.getDate());
for(int i=1;i<=num;i++){
System.out.println(" 第" + i + "期还款日期: " + cal.getTime().toLocaleString());
cal.add(Calendar.DATE, period);
}
}
public static void main(String[] args) {
TestDemo demo = new TestDemo();
demo.huankuan(20000.00, 1, new Date());
}
}
- 用一个方法查出宜个数值类型数组的最大值,用递归方式实现。【高达软件】
方法1
public class Test1 {
public static int a(int[] i,int j){
if(i.length-1>j){
if(i[j]>i[j+1]){
i[j+1]=i[j];
}
return a(i,j+1);
}else{
return i[i.length-1];
}
}
}
方法2 -- 非递归
public static int test(int []num) {
int x=0;
int log = num.Length;
for(intt=0;t
if(num[t]>x){
x=num[t];
}
}return x;
}
方法3 --- 递归 不改变原数组中的元素
public static int getMax(int[]a, int index,int max){
int len = a.length;
if(len==1){
return a[len-1];
}
if(index==0){
max = a[index];
}
if(index==len){
return max;
}
if(max
max = a[index];
}
index++;
return getMax(a,index,max);
}
// 测试
int max = getMax(new int[]{2,5,18,3,38,10,2},0,0);
System.out.println(max);
- 用C编写将一个100以内的自然数分解质因数
/* 100以内素数 */
#include
main()
{
int i,j;
for(i=2;i<100;i++)
{
for(j=2;j
{
if(i%j==0)
break;
}
if(i==j)
{
printf("%d ",i);
}
}
}
/* 分解质因数*/
main()
{
int n,i;
printf( "please input a number:\n ");
scanf( "%d ",&n);
printf( "%d= ",n);
for(i=2;i <=n;i++)
while(n!=i)
{
if(n%i==0)
{
printf( "%d* ",i);
n=n/i;
} else{ break; }
}
printf( "%d ",n);
getch();
}
- 在main方法中将字符串中的数字排序并输出 STRING A="56.89.5.3.75.98.98.26.15.44"
String s=” 56.89.5.3.75.98.98.26.15.44”;
String s1[]=s. split (“.”);
Integer ii[]=new Integer[s1.length];
For(int i=0;i
ii[i]=Integer.parseInt(s1[i]);
}
Arrays.sort(ii);
for(Integer o: ii){
System.out.println(o+” s”);
}
- 用4 个0,用你所知道的数学方法计算出24
0的阶乘等于1 即 0!=1那么4个0就是4了
又4的阶乘为24 4!=24
- 判断身份证:要么是15位,要么是18位,最后一位可以为字母,并写程序提出其中的年月日。
答:我们可以用正则表达式来定义复杂的字符串格式,(\d{17}[0-9a-zA-Z]|\d{14}[0-9a-zA-Z])可以用来判断是否为合法的15位或18位身份证号码。
因为15位和18位的身份证号码都是从7位到第12位为身份证为日期类型。这样我们可以设计出更精确的正则模式,使身份证号的日期合法,这样我们的正则模式可以进一步将日期部分的正则修改为[12][0-9]{3}[01][0-9][123][0-9],当然可以更精确的设置日期。
在jdk的java.util.Regex包中有实现正则的类,Pattern和Matcher。以下是实现代码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTest {
/**
* @param args
*/
public static void main(String[] args) {
// 测试是否为合法的身份证号码
String[] strs = { "130681198712092019", "13068119871209201x",
"13068119871209201", "123456789012345", "12345678901234x",
"1234567890123" };
Pattern p1 = Pattern.compile("(\\d{17}[0-9a-zA-Z]|\\d{14}[0-9a-zA-Z])");
for (int i = 0; i < strs.length; i++) {
Matcher matcher = p1.matcher(strs[i]);
System.out.println(strs[i] + ":" + matcher.matches());
}
Pattern p2 = Pattern.compile("\\d{6}(\\d{8}).*"); // 用于提取出生日字符串
Pattern p3 = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})");// 用于将生日字符串进行分解为年月日
for (int i = 0; i < strs.length; i++) {
Matcher matcher = p2.matcher(strs[i]);
boolean b = matcher.find();
if (b) {
String s = matcher.group(1);
Matcher matcher2 = p3.matcher(s);
if (matcher2.find()) {
System.out
.println("生日为" + matcher2.group(1) + "年"
+ matcher2.group(2) + "月"
+ matcher2.group(3) + "日");
}
}
}
}
}
- 编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替合并到c.txt文件中,a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格进行分隔。
答:
package cn.itcast;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class MainClass{
public static void main(String[] args) throws Exception{
FileManager a = new FileManager("a.txt",new char[]{'\n'});
FileManager b = new FileManager("b.txt",new char[]{'\n',' '});
FileWriter c = new FileWriter("c.txt");
String aWord = null;
String bWord = null;
while((aWord = a.nextWord()) !=null ){
c.write(aWord + "\n");
bWord = b.nextWord();
if(bWord != null)
c.write(bWord + "\n");
}
while((bWord = b.nextWord()) != null){
c.write(bWord + "\n");
}
c.close();
}
}
class FileManager{
String[] words = null;
int pos = 0;
public FileManager(String filename,char[] seperators) throws Exception{
File f = new File(filename);
FileReader reader = new FileReader(f);
char[] buf = new char[(int)f.length()];
int len = reader.read(buf);
String results = new String(buf,0,len);
String regex = null;
if(seperators.length >1 ){
regex = "" + seperators[0] + "|" + seperators[1];
}else{
regex = "" + seperators[0];
}
words = results.split(regex);
}
public String nextWord(){
if(pos == words.length)
return null;
return words[pos++];
}
}
- 编写一个程序,将d:\java目录下的所有.java文件复制到d:\jad目录下,并将原来文件的扩展名从.java改为.jad。
答:listFiles方法接受一个FileFilter对象,这个FileFilter对象就是过虑的策略对象,不同的人提供不同的FileFilter实现,即提供了不同的过滤策略。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Jad2Java {
public static void main(String[] args) throws Exception {
File srcDir = new File("java");
if(!(srcDir.exists() && srcDir.isDirectory()))
throw new Exception("目录不存在");
File[] files = srcDir.listFiles(
new FilenameFilter(){
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
}
);
System.out.println(files.length);
File destDir = new File("jad");
if(!destDir.exists()) destDir.mkdir();
for(File f :files){
FileInputStream fis = new FileInputStream(f);
String destFileName = f.getName().replaceAll("\\.java$", ".jad");
FileOutputStream fos = new FileOutputStream(new File(destDir,destFileName));
copy(fis,fos);
fis.close();
fos.close();
}
}
private static void copy(InputStream ips,OutputStream ops) throws Exception{
int len = 0;
byte[] buf = new byte[1024];
while((len = ips.read(buf)) != -1){
ops.write(buf,0,len);
}
}
}
由本题总结的思想及策略模式的解析:
1.
class jad2java{
1. 得到某个目录下的所有的java文件集合
1.1 得到目录 File srcDir = new File("d:\\java");
1.2 得到目录下的所有java文件:File[] files = srcDir.listFiles(new MyFileFilter());
1.3 只想得到.java的文件: class MyFileFilter implememyts FileFilter{
public boolean accept(File pathname){
return pathname.getName().endsWith(".java")
}
}
2.将每个文件复制到另外一个目录,并改扩展名
2.1 得到目标目录,如果目标目录不存在,则创建之
2.2 根据源文件名得到目标文件名,注意要用正则表达式,注意.的转义。
2.3 根据表示目录的File和目标文件名的字符串,得到表示目标文件的File。
//要在硬盘中准确地创建出一个文件,需要知道文件名和文件的目录。
2.4 将源文件的流拷贝成目标文件流,拷贝方法独立成为一个方法,方法的参数采用抽象流的形式。
//方法接受的参数类型尽量面向父类,越抽象越好,这样适应面更宽广。
}
分析listFiles方法内部的策略模式实现原理
File[] listFiles(FileFilter filter){
File[] files = listFiles();
//Arraylist acceptedFilesList = new ArrayList();
File[] acceptedFiles = new File[files.length];
int pos = 0;
for(File file: files){
boolean accepted = filter.accept(file);
if(accepted){
//acceptedFilesList.add(file);
acceptedFiles[pos++] = file;
}
}
Arrays.copyOf(acceptedFiles,pos);
//return (File[])accpetedFilesList.toArray();
}
- 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉的半个”。
答:
首先要了解中文字符有多种编码及各种编码的特征。
假设n为要截取的字节数。
public static void main(String[] args) throws Exception{
String str = "我a爱中华abc def';
String str = "我ABC汉";
int num = trimGBK(str.getBytes("GBK"),5);
System.out.println(str.substring(0,num) );
}
public static int trimGBK(byte[] buf,int n){
int num = 0;
boolean bChineseFirstHalf = false;
for(int i=0;i
{
if(buf[i]<0 && !bChineseFirstHalf){
bChineseFirstHalf = true;
}else{
num++;
bChineseFirstHalf = false;
}
}
return num;
}
- 有一个字符串,其中包含中文字符、英文字符和数字字符,请统计和打印出各个字符的个数。
答:String content = “中国aadf的111萨bbb菲的zz萨菲”;
HashMap map = new HashMap();
for(int i=0;i
{
char c = content.charAt(i);
Integer num = map.get(c);
if(num == null)
num = 1;
else
num = num + 1;
map.put(c,num);
}
for(Map.EntrySet entry : map)
{
system.out.println(entry.getkey() + “:” + entry.getValue());
}
如果一串字符如"aaaabbc中国1512"要分别统计英文字符的数量,中文字符的数量,和数字字符的数量,假设字符中没有中文字符、英文字符、数字字符之外的其他特殊字符。
int engishCount;
int chineseCount;
int digitCount;
for(int i=0;i
{
char ch = str.charAt(i);
if(ch>=’0’ && ch<=’9’)
{
digitCount++
}
else if((ch>=’a’ && ch<=’z’) || (ch>=’A’ && ch<=’Z’))
{
engishCount++;
}
else
{
chineseCount++;
}
}
System.out.println(……………);
- 从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序:
1,张三,28
2,李四,35
3,张三,28
4,王五,35
5,张三,28
6,李四,35
7,赵六,28
8,田七,35
package com.huawei.interview;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
public class GetNameTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//InputStream ips = GetNameTest.class.getResourceAsStream("/com/huawei/interview/info.txt");
//用上一行注释的代码和下一行的代码都可以,因为info.txt与GetNameTest类在同一包下面,所以,可以用下面的相对路径形式
Map results = new HashMap();
InputStream ips = GetNameTest.class.getResourceAsStream("info.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(ips));
String line = null;
try {
while((line=in.readLine())!=null)
{
dealLine(line,results);
}
sortResults(results);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static class User
{
public String name;
public Integer value;
public User(String name,Integer value)
{
this.name = name;
this.value = value;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
//下面的代码没有执行,说明往treeset中增加数据时,不会使用到equals方法。
boolean result = super.equals(obj);
System.out.println(result);
return result;
}
}
private static void sortResults(Map results) {
// TODO Auto-generated method stub
TreeSet sortedResults = new TreeSet(
new Comparator(){
public int compare(Object o1, Object o2) {
// TODO Auto-generated method stub
User user1 = (User)o1;
User user2 = (User)o2;
/*如果compareTo返回结果0,则认为两个对象相等,新的对象不会增加到集合中去
* 所以,不能直接用下面的代码,否则,那些个数相同的其他姓名就打印不出来。
* */
//return user1.value-user2.value;
//return user1.value
if(user1.value
{
return -1;
}else if(user1.value>user2.value)
{
return 1;
}else
{
return user1.name.compareTo(user2.name);
}
}
}
);
Iterator iterator = results.keySet().iterator();
while(iterator.hasNext())
{
String name = (String)iterator.next();
Integer value = (Integer)results.get(name);
if(value > 1)
{
sortedResults.add(new User(name,value));
}
}
printResults(sortedResults);
}
private static void printResults(TreeSet sortedResults)
{
Iterator iterator = sortedResults.iterator();
while(iterator.hasNext())
{
User user = (User)iterator.next();
System.out.println(user.name + ":" + user.value);
}
}
public static void dealLine(String line,Map map)
{
if(!"".equals(line.trim()))
{
String [] results = line.split(",");
if(results.length == 3)
{
String name = results[1];
Integer value = (Integer)map.get(name);
if(value == null) value = 0;
map.put(name,value + 1);
}
}
}
}
- 写一个Singleton出来。
第一种:饱汉模式
public class SingleTon {
private SingleTon(){
}
//实例化放在静态代码块里可提高程序的执行效率,但也可能更占用空间
private final static SingleTon instance = new SingleTon();
public static SingleTon getInstance(){
return instance;
}
}
第二种:饥汉模式
public class SingleTon {
private SingleTon(){}
private static instance = null;//new SingleTon();
public static synchronized SingleTon getInstance(){
if(instance == null)
instance = new SingleTon();
return instance;
}
}
第三种:用枚举
public enum SingleTon{
ONE;
}
第三:更实际的应用(在什么情况用单例)
public class SequenceGenerator{
//下面是该类自身的业务功能代码
private int count = 0;
public synchronized int getSequence(){
++count;
}
//下面是把该类变成单例的代码
private SequenceGenerator(){}
private final static instance = new SequenceGenerator();
public static SingleTon getInstance(){
return instance;
}
}
第四:
public class MemoryDao
{
private HashMap map = new HashMap();
public void add(Student stu1){
map.put(SequenceGenerator.getInstance().getSequence(),stu1);
}
//把MemoryDao变成单例
}
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
一般Singleton模式通常有几种种形式:
第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。
public class Singleton {
private Singleton(){}
//在自己内部定义自己一个实例,是不是很奇怪?
//注意这是private 只供内部调用
private static Singleton instance = new Singleton();
//这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}
第二种形式:
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
//使用时生成实例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance;
}
}
其他形式:
定义一个类,它的构造函数为private的,所有方法为static的。
一般认为第一种形式要更加安全些
- 一个整数,大于0,不用循环和本地变量,按照n,2n,4n,8n的顺序递增,当值大于5000时,把值按照指定顺序输出来。
例:n=1237
则输出为:
1237,
2474,
4948,
9896,
9896,
4948,
2474,
1237,
提示:写程序时,先致谢按递增方式的代码,写好递增的以后,再增加考虑递减部分。
public static void doubleNum(int n)
{
System.out.println(n);
if(n<=5000)
doubleNum(n*2);
System.out.println(n);
}
Gaibaota(N) = Gaibaota(N-1) + n
|
|
- 第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?
package cn.demo;
import java.util.Date;
public class A1 {
public static void main(String [] args)
{
System.out.println(computeAge(8));
}
public static int computeAge(int n)
{
if(n==1) return 10;
return computeAge(n-1) + 2;
}
}
public static void toBinary(int n,StringBuffer result)
{
if(n/2 != 0)
toBinary(n/2,result);
result.append(n%2);
}
- 排序都有哪几种方法?请列举。用JAVA实现一个快速排序。
交换式排序、选择排序、插入排序、希尔排序、快速排序
public class QuickSort {
/**
* 快速排序
* @param strDate
* @param left
* @param right
*/
public void quickSort(String[] strDate,int left,int right){
String middle,tempDate;
int i,j;
i=left;
j=right;
middle=strDate[(i+j)/2];
do{
while(strDate[i].compareTo(middle)<0&& i i++; //找出左边比中间值大的数
while(strDate[j].compareTo(middle)>0&& j>left)
j--; //找出右边比中间值小的数
if(i<=j){ //将左边大的数和右边小的数进行替换
tempDate=strDate[i];
strDate[i]=strDate[j];
strDate[j]=tempDate;
i++;
j--;
}
}while(i<=j); //当两者交错时停止
if(i quickSort(strDate,i,right);//从
}
if(j>left){
quickSort(strDate,left,j);
}
}
/**
* @param args
*/
public static void main(String[] args){
String[] strVoid=new String[]{"11","66","22","0","55","22","0","32"};
QuickSort sort=new QuickSort();
sort.quickSort(strVoid,0,strVoid.length-1);
for(int i=0;i System.out.println(strVoid[i]+" ");
}
}
}
- 有数组a[n],用java代码将数组元素顺序颠倒
//用下面的也可以
//for(int i=0,int j=a.length-1;i是否等效于 for(int i=0;i呢?
import java.util.Arrays;
public class SwapDemo{
public static void main(String[] args){
int [] a = new int[]{
(int)(Math.random() * 1000),
(int)(Math.random() * 1000),
(int)(Math.random() * 1000),
(int)(Math.random() * 1000),
(int)(Math.random() * 1000)
};
System.out.println(a);
System.out.println(Arrays.toString(a));
swap(a);
System.out.println(Arrays.toString(a));
}
public static void swap(int a[]){
int len = a.length;
for(int i=0;i
int tmp = a[i];
a[i] = a[len-1-i];
a[len-1-i] = tmp;
}
}
}
- 写一个方法,用一个for循环打印九九乘法表 /** *//**
* 打印九九乘法口诀表
*/
public void nineNineMulitTable(){
for (int i = 1,j = 1; j <= 9; i++) {
System.out.print(i+"*"+j+"="+i*j+" ");
if(i==j){
i=0;
j++;
System.out.println();
}
}
}
- 给定一个java.util.Date对象,如何转化为”2007-3-22 20:23:22”格式的字符串。【高达软件】
/** *//**
* 将某个日期以固定格式转化成字符串
* @param date
* @return str
*/
public String date2FormatStr(Date date)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(date);
return str;
}
- 金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
去零的代码:
return sb.reverse().toString().replaceAll("零[拾佰仟]","零").replaceAll("零+万","万").replaceAll("零+元","元").replaceAll("零+","零");
public class RenMingBi {
/**
* @param args add by zxx ,Nov 29, 2008
*/
private static final char[] data = new char[]{
'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'
};
private static final char[] units = new char[]{
'元','拾','佰','仟','万','拾','佰','仟','亿'
};
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(
convert(135689123));
}
public static String convert(int money)
{
StringBuffer sbf = new StringBuffer();
int unit = 0;
while(money!=0)
{
sbf.insert(0,units[unit++]);
int number = money%10;
sbf.insert(0, data[number]);
money /= 10;
}
return sbf.toString();
}
}
- 写一个方法,能够判断任意一个整数是否素数
/** *//**
* 判断任意一个整数是否素数
* @param num
* @return boolean
*/
public boolean isPrimeNumber(int num)
{
for (int i = 2; i <= Math.sqrt(num); i++) {
if(num%i==0)
{
return false;
}
}
return true;
}
- 用1、2、3、4、5这5个数字,用Java写一个Main函数,打印所有不同的排序
static int[] bits = new int[] { 1, 2, 3, 4, 5 };
/**
* @param args
*/
public static void main(String[] args) {
sort("", bits);
}
private static void sort(String prefix, int[] a) {
if (a.length == 1) {
System.out.println(prefix + a[0]);
}
for (int i = 0; i < a.length; i++) {
sort(prefix + a[i], copy(a, i));
}
}
private static int[] copy(int[] a,int index){
int[] b = new int[a.length-1];
System.arraycopy(a, 0, b, 0, index);
System.arraycopy(a, index+1, b, index, a.length-index-1);
return b;
}
- 写一个方法,输入任意一个整数,返回它的阶乘 /** *//** *获得任意一个整数的阶乘
n
!
*/
public int factorial(int num)
{
//递归
if(num == 1)
{
return 1;
}
return num*factorial(num-1);
}
- 写一个方法,用二分查找法判断任意整数在任意整数数组里面是否存在,若存在就返回它在数组中的索引位置,不存在返回-1
/** *//**
*二分查找特定整数在整型数组中的位置(递归)
dataset
data
beginIndex
endIndex
index
*/
public int binarySearch(int[] dataset,int data,int beginIndex,int endIndex){
int midIndex = (beginIndex+endIndex)/2;
//如果查找的数要比开始索引的数据要小或者是比结束索引的书要大,或者开始查找的索引值大于结束的索引值返回-1没有查到
if(data dataset[endIndex]||beginIndex>endIndex){
return -1;
}
if(data return binarySearch(dataset,data,beginIndex,midIndex-1);
}else if(data>dataset[midIndex])
{
return binarySearch(dataset,data,midIndex+1,endIndex);
}else {
return midIndex;
}
}
/** *//**
*二分查找特定整数在整型数组中的位置(非递归)
dataset
data
index
*/
public int binarySearch(int[] dataset ,int data)
{
int beginIndex = 0;
int endIndex = dataset.length - 1;
int midIndex = -1;
if(data dataset[endIndex]||beginIndex>endIndex){
return -1;
}
while(beginIndex <= endIndex) {
midIndex = (beginIndex+endIndex)/2;
if(data endIndex = midIndex-1;
} else if(data>dataset[midIndex]) {
beginIndex = midIndex+1;
}else {
return midIndex;
}
}
return -1;
}
- 如果一个序列的前四个数字分别是2,9,28,65请问第五个数字是?
1³+1=2
2³+1=9
3²+1=28
4³+1=65
所以继续的话应是
5³+1=126
- 编写函数找出1到1000之内能被3整除且不是偶数的整数,并按个位数的大小从大到小排序
public List find() {
List list=new ArrayList();
for (int i = 1; i <=1000; i++) {
if (i%3==0 && i%2!=0) {
list.add(i);
}
}
return list;
}
- 用java方法编写计算指定目录下所有文件占空间大小
//返回文件大小private void getFileSize()throws RuntimeException,IOException
{//初始化文件大小为0;
this.longSize=0;
//如果文件存在而且是文件,直接返回文件大小
if(file.exists()&&file.isFile()){
this.longSize= file.length();
}
//文件存在而且是目录,递归遍历文件目录计算文件大小 else if(file.exists()&&file.isDirectory()){
getFileSize(file);//递归遍历
}else{
throw new RuntimeException("指定文件不存在");
}
}
- 一个list中,有b.a.b.c.b.b.写个方法去掉所有b
public List qub(List list) {
List alist=new ArrayList();
for (int i = 0; i < list.size(); i++) {
String a=(String)list.get(i);
if (!a.equals("b")) {
alist.add(a);
}
}
return alist;
}
- 设计线程的生产者和消费者模式
package com; import java.io.*; import java.util.*; public class Test1 { Vector v = new Vector(); int index = -1; boolean isput = false; public synchronized void put(String name) throws InterruptedException{ if(isput){ wait(); } v.add(name); index++; isput = true; notify(); System.out.println(Thread.currentThread().getName()); } public synchronized void get() throws InterruptedException{ if(!isput){ wait(); } System.out.println(Thread.currentThread().getName()+"取:"+v.get(index)); isput = false; notify(); } public static void main(String[] args) throws CloneNotSupportedException, FileNotFoundException, IOException, InterruptedException { Test1 t = new Test1(); A a = new A(t); B b = new B(t); new Thread(a).start(); new Thread(b).start(); } } class A implements Runnable{ Test1 t; public A(Test1 t){ this.t = t; } @Override public void run() { int i =0 ; while(true){ if(i==0){ try { t.put("男"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else{ try { t.put("女"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } i = (i+1)%2; } } } class B implements Runnable{ Test1 t; public B(Test1 t){ this.t = t; } @Override public void run() { // TODO Auto-generated method stub while(true){ try { t.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } |
- 写一个方法求两个数的公约数
import java.util.ArrayList;
import java.util.List;
public class MaxNum {
int num=0;
public List Maxs(int a){//先找出能被第一个数整除的数
List list=new ArrayList();
for (int i = 1; i <= a; i++) {
if(a%i==0){
list.add(i);
}
}
return list;
}
public void Test(int a,int b){
List list=new MaxNum().Maxs(a);
for (int i = 0; i < list.size(); i++) {
int bb=(Integer) list.get(i);
if(b%bb==0){//找出能被第二个数整出并且也能被第二个数整除的数
num=bb;
}
}
System.out.println("最大公约数为:"+num);
}
public static void main(String[] args) {
new MaxNum().Test(100,1000);
}
}
- 实现字符串的反转。如:abcd 输出dcba
答:
StringBuffer stringBuffer =
new StringBuffer().append("abc").reverse();
System.out.println(stringBuffer.toString());
- 编写程序将由数字及字符组成的字符串中的数字截取出来并按顺序输出,例如:“ABC137GMNQQ2049PN5FFF”输出结果应该为01234579
package com.tarena;
import java.util.Arrays;
public class NumberSplitChar {
public static void main(String[] args) {
String str=”ABC137GMNQQ2049PN5FFF”;
char[] beforechars=str.toCharArray();
char[] afterchars=new char[beforechars.length];
int j=0;
for(int i=0;i
if(beforechars[i]>=’0′ && beforechars[i]<=’9′){
afterchars[j++]=beforechars[i];
}
}
Arrays.sort(afterchars);
for(int i=(afterchars.length-j);i
System.out.print(afterchars[i]);
}
}
}
二、JQuery,JS面试题
- JavaScript有哪几种数据类型
简单:Number,Boolean,String,Null,Undefined
复合:Object,Array,Function
- 在js编码中innerHTML,outhtml,innertext区别
- innerHTML 设置或获取位于对象起始和结束标签内的 HTML
- outerHTML 设置或获取对象及其内容的 HTML 形式
- innerText 设置或获取位于对象起始和结束标签内的文本
- outerText 设置(包括标签)或获取(不包括标签)对象的文本
- 什么是json ,jquery?
JSON: (javaScript Object Notation)是一种轻量级的数据交换格式。
JSON两种结构:
名称/值对的集合,不同的语言中,它被理解为对象,记录,结构,字典,哈希表,有 键列表,关联数组。
值的有序列表,数组
jQuery:
jQuery由美国人John Resig创建 是一个优秀的javascript框架 使用户能够方便的处理HTML documents events 实现动画效果,并且方便地为网站提供AJAX交互。
- jQuery中有id为foo的对象有att属性,如何获取att属性的值?
$(‘foo’).att(‘attr’).val()
- jQuery中添加文本怎么写在div中
【参考】
可以通过jQuery提供的元素选择器或ID选择器为实现,如:
$(‘div’).append(‘Hello ’);要求只能有一个div否则$(‘div’)返回的是数组
$(‘#ID名称’).append(“hello”);
- 你在公司是怎么用jquery的?
【参考】
在项目中是怎么用的是看看你有没有项目经验(根据自己的实际情况来回答)你用过的选择器啊,复选框啊,表单啊,ajax啊,事件等。配置Jquery环境 下载jquery类库 在jsp页面引用jquery类库即可
接下来通过在
- 你为什么要使用jquery?
【参考】
答:因为jQuery是轻量级的框架,大小不到30kb,它有强大的选择器,出色的DOM操作的封装,有可靠的事件处理机制(jQuery在处理事件绑定的时候相当的可靠),完善的ajax(它的ajax封装的非常的好,不需要考虑复杂浏览器的兼容性和XMLHttpRequest对象的创建和使用的问题。) 出色的浏览器的兼容性。 而且支持链式操作,隐式迭代。行为层和结构层的分离,还支持丰富的插件,jquery的文档也非常的丰富。
- 你使用jquery遇到过哪些问题,你是怎么解决的?
【参考】
答:这个答案是开发的,看你是否有相关的项目经验。例 前台拿不到值,JSON 可是出现的错误(多了一个空格等)这编译是不会报错的 jquery库与其他库冲突:
1>如果其他库在jquery库之前导入的话
- 我们可以通过jquery.noconflict()将变量的$的控制权过度给其他库
- 自定义快捷键,用一个变量接住jquery.noconflict()
- 通过函数传参
2>如果jquery库在其他库之前导入就直接使用jquery 今天在处理一个数据问题时,发现jQuery.ajax()方法返回的值一直有问题,清除缓存后数据无误,多次测试后发现返回的值都是之前的值,并且一直未执行url(后台为JAVA,设置断点一直未进入)。在网上查找下,发现是未设置type的原因。如果没设置jQuery.ajax的type="Post",那么ajax就会默认type="Get",这就会导致之前数据被缓存起来。加上type="Post",问题解决!
- 你知道jquery中的选择器吗,请讲一下有哪些选择器?
【参考】
jQuery中的选择器大致分为:基本选择器,层次选择器,过滤选择器,表单选择器
- jquery中的选择器 和 css中的选择器有区别吗?
【参考】
jQuery选择器支持CSS里的选择器,jQuery选择器可用来添加样式和添加相应的行为CSS 中的选择器是只能添加相应的样式
- 你觉得jquery中的选择器有什么优势?
【参考】
简单的写法 $('ID') 来代替 document.getElementById()函数支持CSS1 到CSS3 选择器完善的处理机制(就算写错了id也不会报错)
- 你在使用选择器的时候有有没有什么觉得要注意的地方?
【参考】
- 选择器中含有".","#","[" 等特殊字符的时候需要进行转译
- 属性选择器的引号问题
- 选择器中含有空格的注意事项
- jquery对象和dom对象是怎样转换的?
【参考】
答 :jquery转DOM对象:jQuery 对象是一个数组对象,可以通过[index]的丰富得到相应的DOM对象还可以通过get[index]去得到相应的DOM对象。DOM对象转jQuery对象:$(DOM对象)
- 你是如何使用jquery中的ajax的?
【参考】
如果是一些常规的ajax程序的话,使用load(),$.get(),$.post(),就可以搞定了, 一般我会使用的是$.post() 方法。如果需要设定beforeSend(提交前回调函数),error(失败后处理),success(成功后处理)及complete(请求完成后处理)回调函数等,这个时候我会使用$.ajax()
- 你觉得jquery中的ajax好用吗,为什么?
【参考】
答: 好用的。因为jQuery提供了一些日常开发中夙瑶的快捷操作,例 load,ajax,get,post等等,所以使用jQuery开发ajax将变得极其简单,我们就可以集中精力在业务和用户的体验上,不需要去理会那些繁琐的XMLHttpRequest对象了。
- jquery中$.get()提交和$.post()提交有区别吗?
- $.get() 方法使用GET方法来进行异步请求的。 $.post() 方法使用POST方法来进行异步请求的。
- get请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的。
- get方式传输的数据大小不能超过2KB 而POST要大的多
- GET 方式请求的数据会被浏览器缓存起来,因此有安全问题。
- jquery中的load方法一般怎么用的?
【参考】
答:load方法一般在 载入远程HTML 代码并插入到DOM中的时候用通常用来从Web服务器上获取静态的数据文件。
如果要传递参数的话,可以使用$.get() 或 $.post()
- 在jquery中你是如何去操作样式的?
【参考】
addClass() 来追加样式
removeClass() 来删除样式
toggle() 来切换样式
- 简单的讲叙一下jquery是怎么处理事件的,你用过哪些事件?
【参考】
答: 首先去装载文档,在页面家在完毕后,浏览器会通过javascript 为DOM元素添加事件。
- 你使用过jquery中的动画吗,是怎样用的?
【参考】
答:使用过。hide() 和 show() 同时修改多个样式属性。像高度,宽度,不透明度。 fadeIn() 和fadeOut() fadeTo() 只改变不透明度slideUp() 和 slideDown() slideToggle() 只改变高度animate() 属于自定义动画的方法。
- 你一般用什么去提交数据,为什么?
【参考】
答:一般我会使用的是$.post() 方法。 如果需要设定beforeSend(提交前回调函数),error(失败后处理),success(成功后处理)及complete(请求完成后处理)回调函数等,这个时候我会使用$.ajax()
- 在jquery中引入css有几种方式?
【参考】
答:四种 行内式,内嵌式,导入式,链接式
- 你在jquery中使用过哪些插入节点的方法,它们的区别是什么?
【参考】
答:append(),appendTo(),prepend(),prependTo(),after(),insertAfter() before(),insertBefore() 大致可以分为 内部追加和外部追加
append() 表式向每个元素内部追加内容。
appendTo() 表示 讲所有的元素追加到指定的元素中。例$(A)appendTo(B) 是将A追加到B中 下面的方法解释类似
- jquery中如何来获取或和设置属性?
【参考】
jQuery中可以用attr()方法来获取和设置元素属性
removeAttr() 方法来删除元素属性
- 如何来设置和获取HTML 和文本的值?
【参考】
html()方法 类似于innerHTML属性 可以用来读取或者设置某个元素中的HTML内容 注意:html() 可以用于xhtml文档 不能用于xml文档
text() 类似于innerText属性 可以用来读取或设置某个元素中文本内容。
val() 可以用来设置和获取元素的值
- 子元素选择器 和后代选择器元素有什么区别?
【参考】
答:子代元素是找子节点下的所有元素,后代元素是找子节点或子节点的子节点中的元素
- 你在ajax中使用过JSON吗,你是如何用的?
【参考】
答:使用过,在$.getJSON() 方法的时候就是。因为 $.getJSON() 就是用于加载JSON文件的
- jQuery中有几种方法可以来设置和获取 样式
答 :addClass() 方法,attr() 方法
- $(document).ready()方法和window.onload有什么区别?
【参考】
答: 两个方法有相似的功能,但是在实行时机方面是有区别的。
- window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。
- $(document).ready() 方法可以在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数。
- jQuery是如何处理缓存的?
【参考】
答 :要处理缓存就是禁用缓存.
- 通过$.post() 方法来获取数据,那么默认就是禁用缓存的。
- 通过$.get()方法 来获取数据,可以通过设置时间戳来避免缓存。可以在URL后面加上+(+new Date)例 $.get('ajax.xml?'+(+new Date),function () { //内容 });
- 通过$.ajax 方法来获取数据,只要设置cache:false即可。
- $("#msg").text(); 和 $("#msg").text("new content");有什么区别?
【参考】
1 $("#msg").text() 是 返回id为msg的元素节点的文本内容
2 $("#msg").text("new content"); 是 将“new content” 作为普通文本串写入id为msg的元素节点内容中, 页面显示粗体的new content
- radio单选组的第二个元素为当前选中值,该怎么去取?
【参考】
答 : $('input[name=items]').get(1).checked = true;
- 选择器中 id,class有什么区别?
【参考】
答:在网页中 每个id名称只能用一次,class可以允许重复使用
- 你使用过哪些数据格式,它们各有什么特点?
【参考】
答: HTML格式,JSON格式,javascript格式,XML格式
- HTML片段提供外部数据一般来说是最简单的。
- 如果数据需要重用,而且其他应用程序也可能一次受到影响,那么在性能和文件大小方面具有优势的JSON通常是不错的选择。
- 而当远程应用程序未知时,XML则能够为良好的互操作性提供最可靠的保证。
- jQuery 能做什么?
【参考】
- 获取页面的元素
- 修改页面的外观
- 改变页面大的内容
- 响应用户的页面操作
- 为页面添加动态效果
- 无需刷新页面,即可以从服务器获取信息
- 简化常见的javascript任务
- 在ajax中data主要有几种方式?
【参考】
三种,html拼接的,json数组,form表单经serialize()序列化的。
- jQuery中的hover()和toggle()有什么区别?
【参考】
hover()和toggle()都是jQuery中两个合成事件。hover()方法用于模拟光标悬停事件。toggle()方法是连续点击事件。
- css+div的优势
Div+CSS标准的优点:
1.大大缩减页面代码,提高页面浏览速度,缩减带宽成本;
2.结构清晰,容易被搜索引擎搜索到,天生优化了seo
3.缩短改版时间。只要简单的修改几个CSS文件就可以重新设计一个有成百上千页面的站点。
4.强大的字体控制和排版能力。CSS控制字体的能力比糟糕的FONT标签好多了,有了CSS,我们不再需要用FONT标签或者透明的1 px GIF图片来控制标题,改变字体颜色,字体样式等等。
5.CSS非常容易编写。你可以象写html代码一样轻松地编写CSS。
6.提高易用性。使用CSS可以结构化HTML
- 可以一次设计,随处发布。
更好的控制页面布局
- DIV和Span的区别?
DIV(division)是一个块级元素,可以包含段落、标题、表格,乃至诸如章节、摘要和备注等。而SPAN 是行内元素,SPAN 的前后是不会换行的,它没有结构的意义,纯粹是应用样式,当其他行内元素都不合适时,可以使用SPAN
在 HTML 视图中工作时,可以在
内编辑文本,将某些字包含在
元素内,以强调那些字。与 不同,
和它周围的文本一起移动
- css是什么
层叠样式表,用来进行页面样式设计,美化页面显示。
- ajax的工作原理?
Ajax 基本上就是把 JavaScript 技术和 XMLHttpRequest 对象放在 Web 表单和服务器之间。当用户填写表单时,数据发送给一些 JavaScript 代码而不是 直接发送给服务器。相反,JavaScript 代码捕获表单数据并向服务器发送请求。同时用户屏幕上的表单也不会闪烁、消失或延迟。换句话说,JavaScript 代码在幕后发送请求,用户甚至不知道请求的发出。更好的是,请求是异步发送的,就是说 JavaScript 代码(和用户)不用等待服务器的响应。因此用户可以继续输入数据、滚动屏幕和使用应用程序。
然后,服务器将数据返回 JavaScript 代码(仍然在 Web 表单中),后者决定如何处理这些数据。它可以迅速更新表单数据,让人感觉应用程序是立即完成的,表单没有提交或刷新而用户得到了新数据。JavaScript 代码甚至可以对收到的数据执行某种计算,再发送另一个请求,完全不需要用户干预!这就是 XMLHttpRequest 的强大之处。它可以根据需要自行与服务器进行交互,用户甚至可以完全不知道幕后发生的一切。结果就是类似于桌面应用程序的动态、快速响应、高交互性的体验。
- 在javascript中设置定时调用myfun()函数(周期为1秒)的代码是?
setInterval(myfun(),1000)
- HTTP请求返回的状态码有哪些?分别有什么含义?
3XX:重定向,这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明。
302:请求的资源现在临时从不同的 URI 响应请求
303:对应当前请求的响应可以在另一个 URI 上被找到,而且客户端应当采用 GET 的方式访问那个资源。
4XX:请求错误,这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。
像,403、404、405错误
5XX:服务器错误,这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。
像,500、501、502等错误
- JSON和XML的优缺点
【参考答案】
- 在可读性方面,JSON和XML的数据可读性基本相同。JSON和XML的可读性可谓不相上下,一边是建议的语法,一边是规范的标签形式,很难分出胜负。
- 在可扩展性方面,XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,JSON不能的。
- 在编码难度方面,XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的编码明显比XML容易许多,即使不借助工具也能写出JSON的代码,可是要写好XML就不太容易了。
- 在解码难度方面,XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析难度几乎为0。这一点XML输的真是没话说。
- 在流行度方面,XML已经被业界广泛的使用,而JSON才刚刚开始,但是在Ajax这个特定的领域,未来的发展一定是XML让位于JSON。到时Ajax应该变成Ajaj(Asynchronous Javascript and JSON)了。
- JSON和XML同样拥有丰富的解析手段。
- JSON相对于XML来讲,数据的体积小。
- JSON与JavaScript的交互更加方便。
- JSON对数据的描述性比XML较差。
- JSON的速度要远远快于XML。
三、Web面试题
Java web部分
- JSP有哪些内置对象?作用分别是什么?
答:JSP有9个内置对象:
- request:封装客户端的请求,其中包含来自GET或POST请求的参数;
- response:封装服务器对客户端的响应;
- pageContext:通过该对象可以获取其他对象;
- session:封装用户会话的对象;
- application:封装服务器运行环境的对象;
- out:输出服务器响应的输出流对象;
- config:Web应用的配置对象;
- page:JSP页面本身(相当于Java程序中的this);
- exception:封装页面抛出异常的对象。
- 通过部署描述文件(web.xml)可以配置哪些功能?
【参考答案】
- 配置项目的欢迎页面。
- 配置Servlet访问URL
- 配置Web 容器、Servlet的初始化参数
- 配置错误页面,可以通过异常编号进行错误页面跳转。
- Servlet加载优先级。
- Web容器监听器。
- Web请求过滤器。
- 设置会话的过期时间。
- JSP与SERVLET区别
【参考答案】
JSP在本质上就是SERVLET,但是两者的创建方式不一样.Servlet完全是JAVA程序代码构成,擅长于流程控制;而.JSP由HTML代码和JSP标签构成,可以方便地编写动态网页.因此在实际应用中采用Servlet来控制业务流程,而采用JSP来生成动态网页,同时在MVC设计模式中JSP充当视图层,而Servlet位于控制层。另外JSP也是Servlet技术的扩展,本质上就是Servlet,就是JSP的另一种简易体现形式,因为JSP编译后就是一个“类servlet”,再经由JVM编译生成Java类文件来执行。
- Tomcat的class加载的优先顺序一览
【参考答案】
加载顺序图示如下:

第一步:加载JVM类库。一般是加载由虚拟机提供的基本的运行时类和系统扩展目录($JAVA_HOME/jre/lib/ext)下的JAR包。
第二步:加载系统环境变量的类库。这个加载器用来加载CLASSPATH环境变量中指定的类。
第三步:加载Tomcat下面common文件夹下面的公共类库。
第四步:加载自己需要的catalina类库。
第五步:webapps下面自己应用的类库,包括webapp1、webapp1......等。
- Servlet中的init()方法什么时候被调用?
【参考答案】
当客户端第一次请求该Servlet时,由容器调用该Servlet类的init()方法对该Servlet进行初始化,该初始始化方法只被调用一次。
- 用什么方法使服务器关闭之后,session所保存的信息不会丢失?
【参考答案】
使用cookie实现,服务器端将需要保存的信息,通过Cookie并写入客户端磁盘中,下次访问时,客户端浏览器携带写入的信息提交至服务器,这样可以使信息不会因服务器关闭而丢失。
【分析】
主要考查Cookie的相关知识,比如还有一道题问:如果登录某个网站后,想在本周内都不用重新登录,也是通过Cookie实现的
- Forward与Redirect 的区别?有哪些方式实现
【参考答案】
forward是服务器资源转发,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,客户机并不知道发送的内容是从哪儿来的,所以地址栏中还是原来的地址;redirect则是服务器收到请求后发送一个状态头给客户,客户将再请求一次,这里多了两次网络通信的来往。forward 会将请求状态和信息发至下一个jsp或Servlet。redirect 是送到 client 端后再一次请求,信息不被保留,就是我们说的无法获取request中的参数。
实现方式:
HttpServletResponse接口sendRedirect()方法进行重定向转发
RequestDispatcher.接口forward()方法进行请求转发
- Servlet的生命周期分为3个阶段?
【参考答案】
Servlet的生命周期主要由3个过程组成。
(1)init()方法:服务器初始化servlet。
(2)service()方法:初始化完毕,servlet对象调用该方法响应客户的请求。
(3)destroy()方法:调用该方法消灭servlet对象。
其中,init()方法只在servlet第一次被请求加载的时候被调用一次,当有客户再请求servlet服务时,web服务器将启动一个新的线程,在该线程中,调用service方法响应客户的请求。
- 描述Cookie和Session的作用?区别和各自的应用范围?Session工作原理。【北京科瑞明】
【参考答案】
Cookie和Session都是用来服务器端和客户端进行会话跟踪的一种技术。
区别:Cookie只能传输字符数据,字符是通过加密后写到客户端,下次请求时协带至服务器端,Cookie协带的数据大小为4KB,对数据量超出4KB的数据,无法处理,Cookie数据一般是通过加密后存储在客户端,而Session在服务器端和浏览器缓存中都保存在ID的值,通过此ID来识别唯一的客户端。Session对数据存储的大小没有限制,但存储的信息加重服务器的负载,另外Session在分布式服务器的使用上也有限制,Session无法跨域,也就是多台服务器无法共享会话。
Session原理:当客户端用户访问时,服务器都为每个用户分配一个唯一的会话ID(Session ID) 保存在服务器内存中,服务器响应客户端时,将Session ID写入浏览器缓存中,当下次客户端请求时,就会将该Session ID携带至服务器,服务器再根据ID比对,识别不同客户端请求,以此方式来不断维持服务器和客户端状态跟踪。
- HTTP请求的GET与POST方式的区别
【参考答案】
GET 和 POST.是HTTP定义的与服务器交互的不同方法,是使用HTTP的标准协议动词,用于编码和传送变量名/变量值对参数,并且使用相关的请求语义。
1、Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交,无法在地址栏看到。
2、GET方式提交的数据最多只能有1024字节,而POST则没有此限制。
3、GET一般用作小数据量的请求,POST一般用作大数据量的请求,如:附件。
- 什么情况下调用doGet()和doPost()?
【参考答案】
根据客户端的请求的方式来决定调用哪个方法处理请求,如果客户端采用GET方式
发送请求,服务器端则采用doGET()来处理,如果采用post方式,服务器端则采用doPOST()
- request.getAttribute() 和 request.getParameter() 有何区别?
【参考答案】
request.getAttribute()获取在请求对象中设置的属性,该方法返回对象为Object类型,而getParameter()方法是获取指定的请求参数值,返回值为String类型的字符串。
- JSP的常用指令
【参考答案】
共三种,分别是:
- <%@include >用来在JSP页面包含静态资源
- <%@taglib >用来指定JSP页面标签类型
- <%@page >用来指定页面相关属性
- 页面间对象传递的方法
【参考答案】
request、session、application、Cookie等,其中比较常用的像request、Session。request主要是应用在同一请求周期内,可能进行对象或参数的共享传递。而Session主要可以应用于同一客户端会话周期内进行参数属性的共享。
- web运用程序的稳定、安全需要考虑哪些?
【参考答案】
Web服务器的性能考虑主要有:并发用户数、事务安全、负载均衡、时段流量、网络带宽
网格安全等。
网络安全方面:
- 关键数据的保护,例如用户数据等
- 功能服务的正常提供。
- 网站的防攻击能力。
- 对异常灾害的恢复能力。
程序性能:
- 响应请求并运行得出结果的时间。
- 错误的检测和拦截。
- 扩展性。
- 将ISO8859-1字符串转成GB2312编码,语句为?
【参考答案】
String s=new String(text.getBytes(“iso8859-1”),”gb2312”)
- 哪些方法可以提高JDBC性能?
【参考答案】
1. 使用数据连接池(Connection Pool), 避免使用DriverManager.getConnection()。
- 合理的配置数据连接池参数,合理如何设置数据连接池的初始大小
- 选择合适的事务等级,按照不同的数据库操作类型选择不同的事务等级。
- 及时关闭Connection,不关闭的话会严重影响系统的性能,甚至造成系统罢工
5. 优化Statement
1) 选择合适的Statement, 根据不同的数据库操作选择Statement, PreparedStatement 或者 CallableStatement
2) 尽可能的使用batch, 这样可以减少调用JDBC的次数。
3) Statement执行完毕后关闭Statement
6. 优化你的SQL, 尽量减少你的结果集,不要每次都"select * from XXX"
7. 使用一些缓存工具进行缓存,特别是大数据查询。
- Web容器里面的对象存活周期?
【参考答案】
当然由web容器进行创建管理的对象主要有application,session,request,page这四个级别的对象,而这4种级别的对象,根据它们自身的特点来管理所持的对象,如:request中的对象的生命周期就是在请求范围内,Session在是会话周期内,page是在当前JSP Page内,Application是在服务器启、停的周期内。
【分析】
总的来说这道题有点没明白,提问者想问的是东西是什么。看到题第一反应以为是问Servlet的生存周期,因为说到Web容器对象,一般指的是Servlet,Servlet组件是由容器进行创建、调用和管理的,所以首先想到了Servlet的存活周期。
- 浏览器页面与Tomcat的交互过程?
【参考答案】
当一个JSP页面第一次被访问的时候,JSP引擎将执行以下步骤:
(1)将JSP页面翻译成一个Servlet,这个Servlet是一个java文件,同时也是一个完整的java程序
(2)再由java编译器对这个Servlet进行编译,得到可执行class文件
(3)再由JVM解释器来解释执行class文件,生成向客户端发送的应答,然后发送给客户端
以上三个步骤仅仅在JSP页面第一次被访问时才会执行,以后的访问速度会因为class文件已经生成而大大提高。
- 常用的Web服务器有哪些?
答:Unix和Linux平台下使用最广泛的免费HTTP服务器是Apache服务器,而Windows平台的服务器通常使用IIS作为Web服务器。选择Web服务器应考虑的因素有:性能、安全性、日志和统计、虚拟主机、代理服务器、缓冲服务和集成应用程序等。下面是对常见服务器的简介:
- IIS:Microsoft的Web服务器产品,全称是Internet Information Services。IIS是允许在公共Intranet或Internet上发布信息的Web服务器。IIS是目前最流行的Web服务器产品之一,很多著名的网站都是建立在IIS的平台上。IIS提供了一个图形界面的管理工具,称为Internet服务管理器,可用于监视配置和控制Internet服务。IIS是一种Web服务组件,其中包括Web服务器、FTP服务器、NNTP服务器和SMTP服务器,分别用于网页浏览、文件传输、新闻服务和邮件发送等方面,它使得在网络(包括互联网和局域网)上发布信息成了一件很容易的事。它提供ISAPI(Intranet Server API)作为扩展Web服务器功能的编程接口;同时,它还提供一个Internet数据库连接器,可以实现对数据库的查询和更新。
- Kangle:Kangle Web服务器是一款跨平台、功能强大、安全稳定、易操作的高性能Web服务器和反向代理服务器软件。此外,Kangle也是一款专为做虚拟主机研发的Web服务器。实现虚拟主机独立进程、独立身份运行。用户之间安全隔离,一个用户出问题不影响其他用户。支持PHP、ASP、ASP.NET、Java、Ruby等多种动态开发语言。
- WebSphere:WebSphere Application Server是功能完善、开放的Web应用程序服务器,是IBM电子商务计划的核心部分,它是基于Java的应用环境,用于建立、部署和管理Internet和Intranet Web应用程序,适应各种Web应用程序服务器的需要。
- WebLogic:WebLogic Server是一款多功能、基于标准的Web应用服务器,为企业构建企业应用提供了坚实的基础。针对各种应用开发、关键性任务的部署,各种系统和数据库的集成、跨Internet协作等Weblogic都提供了相应的支持。由于它具有全面的功能、对开放标准的遵从性、多层架构、支持基于组件的开发等优势,很多公司的企业级应用都选择它来作为开发和部署的环境。WebLogic Server在使应用服务器成为企业应用架构的基础方面一直处于领先地位,为构建集成化的企业级应用提供了稳固的基础。
- Apache:目前Apache仍然是世界上用得最多的Web服务器,其市场占有率很长时间都保持在60%以上(目前的市场份额约40%左右)。世界上很多著名的网站都是Apache的产物,它的成功之处主要在于它的源代码开放、有一支强大的开发团队、支持跨平台的应用(可以运行在几乎所有的Unix、Windows、Linux系统平台上)以及它的可移植性等方面。
- Tomcat:Tomcat是一个开放源代码、运行Servlet和JSP的容器。Tomcat实现了Servlet和JSP规范。此外,Tomcat还实现了Apache-Jakarta规范而且比绝大多数商业应用软件服务器要好,因此目前也有不少的Web服务器都选择了Tomcat。
- Nginx:读作"engine x",是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。 Nginx是由Igor Sysoev为俄罗斯访问量第二的Rambler站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。在2014年下半年,Nginx的市场份额达到了14%。
- 过滤器有哪些作用和用法?
答: Java Web开发中的过滤器(filter)是从Servlet 2.3规范开始增加的功能,并在Servlet 2.4规范中得到增强。对Web应用来说,过滤器是一个驻留在服务器端的Web组件,它可以截取客户端和服务器之间的请求与响应信息,并对这些信息进行过滤。当Web容器接受到一个对资源的请求时,它将判断是否有过滤器与这个资源相关联。如果有,那么容器将把请求交给过滤器进行处理。在过滤器中,你可以改变请求的内容,或者重新设置请求的报头信息,然后再将请求发送给目标资源。当目标资源对请求作出响应时候,容器同样会将响应先转发给过滤器,在过滤器中你可以对响应的内容进行转换,然后再将响应发送到客户端。
常见的过滤器用途主要包括:对用户请求进行统一认证、对用户的访问请求进行记录和审核、对用户发送的数据进行过滤或替换、转换图象格式、对响应内容进行压缩以减少传输量、对请求或响应进行加解密处理、触发资源访问事件、对XML的输出应用XSLT等。
和过滤器相关的接口主要有:Filter、FilterConfig和FilterChain。
- 监听器有哪些作用和用法?
答:Java Web开发中的监听器(listener)就是application、session、request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件,如下所示:
①ServletContextListener:对Servlet上下文的创建和销毁进行监听。
②ServletContextAttributeListener:监听Servlet上下文属性的添加、删除和替换。
③HttpSessionListener:对Session的创建和销毁进行监听。
④HttpSessionAttributeListener:对Session对象中属性的添加、删除和替换进行监听。
⑤ServletRequestListener:对请求对象的初始化和销毁进行监听。
⑥ServletRequestAttributeListener:对请求对象属性的添加、删除和替换进行监听。
- 你的项目中使用过哪些JSTL标签?
答:项目中主要使用了JSTL的核心标签库,包括、、、、等,主要用于构造循环和分支结构以控制显示逻辑。
- 使用标签库有什么好处?
答:使用标签库的好处包括以下几个方面:
- 分离JSP页面的内容和逻辑,简化了Web开发;
- 开发者可以创建自定义标签来封装业务逻辑和显示逻辑;
- 标签具有很好的可移植性、可维护性和可重用性;
- 避免了对Scriptlet(小脚本)的使用(很多公司的项目开发都不允许在JSP中书写小脚本)
- 表达式语言(EL)支持哪些运算符?
答:除了.和[]运算符,EL还提供了:
- 算术运算符:+、-、*、/或div、%或mod
- 关系运算符:==或eq、!=或ne、>或gt、>=或ge、<或lt、<=或le
- 逻辑运算符:&&或and、||或or、!或not
- 条件运算符:${statement? A : B}(跟Java的条件运算符类似)
- empty运算符:检查一个值是否为null或者空(数组长度为0或集合中没有元素也返回true)
- Java Web开发的Model 1和Model 2分别指的是什么?
答:Model 1是以页面为中心的Java Web开发,使用JSP+JavaBean技术将页面显示逻辑和业务逻辑处理分开,JSP实现页面显示,JavaBean对象用来保存数据和实现业务逻辑。Model 2是基于MVC(模型-视图-控制器,Model-View-Controller)架构模式的开发模型,实现了模型和视图的彻底分离,利于团队开发和代码复用。
- 实现会话跟踪的技术有哪些?
答:由于HTTP协议本身是无状态的,服务器为了区分不同的用户,就需要对用户会话进行跟踪,简单的说就是为用户进行登记,为用户分配唯一的ID,下一次用户在请求中包含此ID,服务器据此判断到底是哪一个用户。
①URL 重写:在URL中添加用户会话的信息作为请求的参数,或者将唯一的会话ID添加到URL结尾以标识一个会话。
②设置表单隐藏域:将和会话跟踪相关的字段添加到隐式表单域中,这些信息不会在浏览器中显示但是提交表单时会提交给服务器。
这两种方式很难处理跨越多个页面的信息传递,因为如果每次都要修改URL或在页面中添加隐式表单域来存储用户会话相关信息,事情将变得非常麻烦。
③cookie:cookie有两种,一种是基于窗口的,浏览器窗口关闭后,cookie就没有了;另一种是将信息存储在一个临时文件中,并设置存在的时间。当用户通过浏览器和服务器建立一次会话后,会话ID就会随响应信息返回存储在基于窗口的cookie中,那就意味着只要浏览器没有关闭,会话没有超时,下一次请求时这个会话ID又会提交给服务器让服务器识别用户身份。会话中可以为用户保存信息。会话对象是在服务器内存中的,而基于窗口的cookie是在客户端内存中的。如果浏览器禁用了cookie,那么就需要通过下面两种方式进行会话跟踪。当然,在使用cookie时要注意几点:首先不要在cookie中存放敏感信息;其次cookie存储的数据量有限(4k),不能将过多的内容存储cookie中;再者浏览器通常只允许一个站点最多存放20个cookie。当然,和用户会话相关的其他信息(除了会话ID)也可以存在cookie方便进行会话跟踪。
④HttpSession:在所有会话跟踪技术中,HttpSession对象是最强大也是功能最多的。当一个用户第一次访问某个网站时会自动创建HttpSession,每个用户可以访问他自己的HttpSession。可以通过HttpServletRequest对象的getSession方法获得HttpSession,通过HttpSession的setAttribute方法可以将一个值放在HttpSession中,通过调用HttpSession对象的getAttribute方法,同时传入属性名就可以获取保存在HttpSession中的对象。与上面三种方式不同的是,HttpSession放在服务器的内存中,因此不要将过大的对象放在里面,即使目前的Servlet容器可以在内存将满时将HttpSession中的对象移到其他存储设备中,但是这样势必影响性能。添加到HttpSession中的值可以是任意Java对象,这个对象最好实现了Serializable接口,这样Servlet容器在必要的时候可以将其序列化到文件中,否则在序列化时就会出现异常。
- 如何在基于Java的Web项目中实现文件上传和下载?
答:在Sevlet 3 以前,Servlet API中没有支持上传功能的API,因此要实现上传功能需要引入第三方工具从POST请求中获得上传的附件或者通过自行处理输入流来获得上传的文件,我们推荐使用Apache的commons-fileupload。
- 如何设置请求的编码以及响应内容的类型?
答:通过请求对象(ServletRequest)的setCharacterEncoding(String)方法可以设置请求的编码,其实要彻底解决乱码问题就应该让页面、服务器、请求和响应、Java程序都使用统一的编码,最好的选择当然是UTF-8;通过响应对象(ServletResponse)的setContentType(String)方法可以设置响应内容的类型,当然也可以通过HttpServletResponsed对象的setHeader(String, String)方法来设置。
- 解释一下网络应用的模式及其特点。
答:典型的网络应用模式大致有三类:B/S、C/S、P2P。其中B代表浏览器(Browser)、C代表客户端(Client)、S代表服务器(Server),P2P是对等模式,不区分客户端和服务器。B/S应用模式中可以视为特殊的C/S应用模式,只是将C/S应用模式中的特殊的客户端换成了浏览器,因为几乎所有的系统上都有浏览器,那么只要打开浏览器就可以使用应用,没有安装、配置、升级客户端所带来的各种开销。P2P应用模式中,成千上万台彼此连接的计算机都处于对等的地位,整个网络一般来说不依赖专用的集中服务器。网络中的每一台计算机既能充当网络服务的请求者,又对其它计算机的请求作出响应,提供资源和服务。通常这些资源和服务包括:信息的共享和交换、计算资源(如CPU的共享)、存储共享(如缓存和磁盘空间的使用)等,这种应用模式最大的阻力安全性、版本等问题,目前有很多应用都混合使用了多种应用模型,最常见的网络视频应用,它几乎把三种模式都用上了。四、
四、框架面试题
Spring Boot总结
1、什么是SpringBoot
描述:Spring Boot是Spring社区发布的一个开源项目,旨在帮助开发者快速并且更简单的构建项目。大多数SpringBoot项目只需要很少的配置文件。
2、SpringBoot核心功能
2.1、独立运行Spring项目
Spring boot 可以以jar包形式独立运行,运行一个Spring Boot项目只需要通过java -jar xx.jar来运行。
2.2、内嵌servlet容器
Spring Boot可以选择内嵌Tomcat、jetty或者Undertow,这样我们无须以war包形式部署项目。
2.3、提供starter简化Maven配置
spring提供了一系列的start pom来简化Maven的依赖加载,例如,当你使用了spring-boot-starter-web,会自动加入如图5-1所示的依赖包。
2.4、自动装配Spring
SpringBoot会根据在类路径中的jar包,类、为jar包里面的类自动配置Bean,这样会极大地减少我们要使用的配置。当然,SpringBoot只考虑大多数的开发场景,并不是所有的场景,若在实际开发中我们需要配置Bean,而SpringBoot灭有提供支持,则可以自定义自动配置。
2.5、准生产的应用监控
SpringBoot提供基于http ssh telnet对运行时的项目进行监控。
2.6、无代码生产和xml配置
SpringBoot不是借助与代码生成来实现的,而是通过条件注解来实现的,这是Spring4.x提供的新特性。
3、SpringBoot优缺点
优点:
3.1、快速构建项目。
3.2、对主流开发框架的无配置集成。
3.3、项目可独立运行,无须外部依赖Servlet容器。
3.4、提供运行时的应用监控。
3.5、极大的提高了开发、部署效率。
3.6、与云计算的天然集成。
缺点:
3.1、如果你不认同spring框架,也许这就是缺点。
4、SpringBoot特性
4.1、创建独立的Spring项目
4.2、内置Tomcat和Jetty容器
4.3、提供一个starter POMs来简化Maven配置
4.4、提供了一系列大型项目中常见的非功能性特性,如安全、指标,健康检测、外部配置等
4.5、完全没有代码生成和xml配置文件
6、SpringBoot CLI
SpringBoot CLI 是SpringBoot提供的控制台命令工具。
7、SpringBoot maven 构建项目
spring-boot-starter-parent:是一个特殊Start,它用来提供相关的Maven依赖项,使用它之后,常用的包依赖可以省去version标签。
8、SpringBoot几个常用的注解
(1)@RestController和@Controller指定一个类,作为控制器的注解
(2)@RequestMapping方法级别的映射注解,这一个用过Spring MVC的小伙伴相信都很熟悉
(3)@EnableAutoConfiguration和@SpringBootApplication是类级别的注解,根据maven依赖的jar来自动猜测完成正确的spring的对应配置,只要引入了spring-boot-starter-web的依赖,默认会自动配置Spring MVC和tomcat容器
(4)@Configuration类级别的注解,一般这个注解,我们用来标识main方法所在的类,完成元数据bean的初始化。
(5)@ComponentScan类级别的注解,自动扫描加载所有的Spring组件包括Bean注入,一般用在main方法所在的类上
(6)@ImportResource类级别注解,当我们必须使用一个xml的配置时,使用@ImportResource和@Configuration来标识这个文件资源的类。
(7)@Autowired注解,一般结合@ComponentScan注解,来自动注入一个Service或Dao级别的Bean
(8)@Component类级别注解,用来标识一个组件,比如我自定了一个filter,则需要此注解标识之后,Spring Boot才会正确识别。
Spring Boot、Spring MVC 和 Spring 有什么区别?
SpringFrame
SpringFramework 最重要的特征是依赖注入。所有 SpringModules 不是依赖注入就是 IOC 控制反转。
当我们恰当的使用 DI 或者是 IOC 的时候,我们可以开发松耦合应用。松耦合应用的单元测试可以很容易的进行。
SpringMVC
Spring MVC 提供了一种分离式的方法来开发 Web 应用。通过运用像 DispatcherServelet,MoudlAndView 和 ViewResolver 等一些简单的概念,开发 Web 应用将会变的非常简单。
SpringBoot
Spring 和 SpringMVC 的问题在于需要配置大量的参数。
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
/WEB-INF/views/
.jsp
Spring Boot 通过一个自动配置和启动的项来目解决这个问题。为了更快的构建产品就绪应用程序,Spring Boot 提供了一些非功能性特征。
Spring Boot 还提供了其它的哪些 Starter Project Options?
Spring Boot 也提供了其它的启动器项目包括,包括用于开发特定类型应用程序的典型依赖项。
spring-boot-starter-web-services - SOAP Web Services
spring-boot-starter-web - Web 和 RESTful 应用程序
spring-boot-starter-test - 单元测试和集成测试
spring-boot-starter-jdbc - 传统的 JDBC
spring-boot-starter-hateoas - 为服务添加 HATEOAS 功能
spring-boot-starter-security - 使用 SpringSecurity 进行身份验证和授权
spring-boot-starter-data-jpa - 带有 Hibeernate 的 Spring Data JPA
spring-boot-starter-data-rest - 使用 Spring Data REST 公布简单的 REST 服务
(1) Spring在SSM起什么作用
Spring是一个轻量级框架,也是一个容器,Spring实质上讲就是一个Bean工厂,主要用来管理Bean的生命周期和框架集成。有IOC控制反转,DI依赖注入,控制反转是把dao依赖注入到servic层,然后service层反转给action层,Spring的顶层容器为BeanFactory,常用的ApplicationContext为它的子接口,实现了工厂模式,Spring还提供了AOP的支持,方便在切面级开发,
(2) 怎么样理解IOC和DI
在使用Spring框架的过程中、一定会用到控制反转、但是往往所需要的资源还需要其他资源的支持、个过程就需要依赖注入的支持
(3)Spring的事务,事务的作用。
• 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
• 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。
(3) Spring的IOC你在项目中是怎么使用的?
• IOC主要来解决对象之间的依赖问题,把所有的bean的依赖关系通过配置文件或者注解关联起来,降低了耦合度
高内聚、低耦合
(5)Spring的配置文件有哪些内容?
• 开启事务注解驱动
• 事务管理器
• 开启注解功能,并配置扫描包
• 配置数据源
• 配置SQL会话工厂、别名、映射文件
• 不用编写DAO层的实现类(代理模式)
(6)说下Spring的注解
• @Controller
• @Service
• @Component
• @RequestMapping
• @Resource、@Autowired
• @ResponseBody
• @Transactional
(7)为什么要用Spring
• 降低对象耦合度,让代码更加清晰,提供一些常见的模版
(8)Spring DI的几种方式
• (1)构造器注入:通过构造方法初始化
•
• (2)setter注入:通过setter方法初始化注入
•
• 注意:在实际开发中常用setter注入。
(1)SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决
是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写字段
(2)SpingMvc中的控制器的注解
@Controller 注解:该注解表明该类扮演控制器的角色,Spring不需要你继承任何其他控制器基类或引用Servlet API。
(3)@RequestMapping注解用在类上面有什么作用
该注解是用来映射一个URL到一个类或一个特定的方处理法上。
(4) 我想在拦截的方法里面得到从前台传入的参数,怎么得到
直接在形参里面声明这个参数就可以,但必须名字和传过来的参数一样
(5)如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象
直接在方法中声明这个对象,SpringMvc就自动会把属性赋值到这个对象里面
(6)SpringMvc中函数的返回值是什么
返回值可以有很多类型,有String, ModelAndView,List,Set等,一般用String比较好,如果是AJAX请求,返回的可以是一个集合
(7)SpringMvc怎么处理返回值的
SpringMvc根据配置文件中InternalResourceViewResolver(内部资源视图解析器)的前缀和后缀,用前缀+返回值+后缀组成完整的返回值
(8)SpringMVC怎么样设定重定向和转发的
在返回值前面加"forward:"就可以让结果转发,譬如"forward:user.do?name=method4" 在返回值前面加"redirect:"就可以让返回值重定向,譬如"redirect:http://www.uu456.com"
(9)SpringMvc中有个类把视图和数据都合并的一起的,叫什么
ModelAndView
(10)怎么样把数据放入Session里面
可以声明一个request,或者session先拿到session,然后就可以放入数据,或者可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key
(11)SpringMvc怎么和AJAX相互调用的
通过Jackson框架就可以把Java里面的对象直接转化成js可以识别的Json对象 具体步骤如下 :
1.加入Jackson.jar
2.在配置文件中配置json的映射
3.在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上@ResponseBody注解
(12)当一个方法向AJAX返回对象,譬如Object,List等,需要做什么处理
要加上@ResponseBody注解
(13)讲下SpringMvc的执行流程
系统启动的时候根据配置文件创建spring的容器, 首先是发送http请求到核心控制器DispatcherServlet,spring容器通过映射器去寻找业务控制器,
使用适配器找到相应的业务类,在进业务类时进行数据封装,在封装前可能会涉及到类型转换,执行完业务类后使用ModelAndView进行视图转发,
数据放在model中,用map传递数据进行页面显示。
(1)什么是MyBatis的接口绑定,有什么好处
接口映射就是在IBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们直接调用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置.
(2)什么情况下用注解绑定,什么情况下用xml绑定
当Sql语句比较简单时候,用注解绑定,当SQL语句比较复杂时候,用xml绑定,一般用xml绑定的比较多
(3)如果要查询的表名和返回的实体Bean对象不一致,那你是怎么处理的?
在MyBatis里面最主要最灵活的的一个映射对象的ResultMap,在它里面可以映射键值对, 默认里面有id节点,result节点,它可以映射表里面的列名和对象里面的字段名. 并且在一对一,一对多的情况下结果集也一定要用ResultMap
(4)MyBatis在核心处理类叫什么
MyBatis里面的核心处理类叫做SqlSession
(5)讲下MyBatis的缓存
MyBatis的缓存分为一级缓存和二级缓存,一级缓存放在session里面,默认就有,二级缓存放在它的命名空间里,
默认是打开的,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置
(6)MyBatis(IBatis)的好处是什么
ibatis把sql语句从Java源程序中独立出来,放在单独的XML文件中编写,给程序的
维护带来了很大便利。
ibatis封装了底层JDBC API的调用细节,并能自动将结果集转换成JavaBean对象,大大简化了Java数据库编程的重复工作。
因为Ibatis需要程序员自己去编写sql语句,程序员可以结合数据库自身的特点灵活控制sql语句,
因此能够实现比hibernate等全自动orm框架更高的查询效率,能够完成复杂查询。
(7)MyBatis怎么配置一对多?
一对多的关系 :property: 指的是集合属性的值, ofType:指的是集合中元素的类型
(8)MyBatis怎样配置多对一?
多对一的关系:property: 指的是属性的值, javaType:指的是属性的类型
五、数据库面试题
Student(SId,Sname,Sage,Ssex) 学生表
Course(CId,Cname,TId) 课程表
SC(SId,CId,score) 成绩表
Teacher(TId,Tname) 教师表
问题:
1、查询“001”课程比“002”课程成绩高的所有学生的学号;
select a.SId from (select sId,score from SC where CId='001') a,(select sId,score
from SC where CId='002') b
where a.score>b.score and a.sId=b.sId;
2、查询平均成绩大于60分的同学的学号和平均成绩;
select SId,avg(score)
from sc
group by SId having avg(score) >60;
3、查询所有同学的学号、姓名、选课数、总成绩;
select Student.SId,Student.Sname,count(SC.CId),sum(score)
from Student left Outer join SC on Student.SId=SC.SId
group by Student.SId,Sname
4、查询姓“李”的老师的个数;
select count(distinct(Tname))
from Teacher
where Tname like '李%';
5、查询没学过“叶平”老师课的同学的学号、姓名;
select Student.SId,Student.Sname
from Student
where SId not in (select distinct( SC.SId) from SC,Course,Teacher where SC.CId=Course.CId and Teacher.TId=Course.TId and Teacher.Tname='叶平');
6、查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
select Student.SId,Student.Sname from Student,SC where Student.SId=SC.SId and SC.CId='001'and exists( Select * from SC as SC_2 where SC_2.SId=SC.SId and SC_2.CId='002');
7、查询学过“叶平”老师所教的所有课的同学的学号、姓名;
select SId,Sname
from Student
where SId in (select SId from SC ,Course ,Teacher where SC.CId=Course.CId and Teacher.TId=Course.TId and Teacher.Tname='叶平' group by SId having count(SC.CId)=(select count(CId) from Course,Teacher where Teacher.TId=Course.TId and Tname='叶平'));
8、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
Select SId,Sname from (select Student.SId,Student.Sname,score ,(select score from SC SC_2 where SC_2.SId=Student.SId and SC_2.CId='002') score2
from Student,SC where Student.SId=SC.SId and CId='001') S_2 where score2
9、查询所有课程成绩小于60分的同学的学号、姓名;
select SId,Sname
from Student
where SId not in (select Student.SId from Student,SC where S.SId=SC.SId and score>60);
10、查询没有学全所有课的同学的学号、姓名;
select Student.SId,Student.Sname
from Student,SC
where Student.SId=SC.SId group by Student.SId,Student.Sname having count(CId) <(select count(CId) from Course);
11、查询至少有一门课与学号为“1001”的同学所学相同的同学的学号和姓名;
select SId,Sname from Student,SC where Student.SId=SC.SId and CId in select CId from SC where SId='1001';
12、查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名;
select distinct SC.SId,Sname
from Student,SC
where Student.SId=SC.SId and CId in (select CId from SC where SId='001');
13、把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩;
update SC set score=(select avg(SC_2.score)
from SC SC_2
where SC_2.CId=SC.CId ) from Course,Teacher where Course.CId=SC.CId and Course.TId=Teacher.TId and Teacher.Tname='叶平');
14、查询和“1002”号的同学学习的课程完全相同的其他同学学号和姓名;
select SId from SC where CId in (select CId from SC where SId='1002')
group by SId having count(*)=(select count(*) from SC where SId='1002');
15、删除学习“叶平”老师课的SC表记录;
Delect SC
from course ,Teacher
where Course.CId=SC.CId and Course.TId= Teacher.TId and Tname='叶平';
16、向SC表中插入一些记录,这些记录要求符合以下条件:没有上过编号“003”课程的同学学号、2、
号课的平均成绩;
Insert SC select SId,'002',(Select avg(score)
from SC where CId='002') from Student where SId not in (Select SId from SC where CId='002');
17、按平均成绩从高到低显示所有学生的“数据库”、“企业管理”、“英语”三门的课程成绩,按如下形式显示: 学生ID,,数据库,企业管理,英语,有效课程数,有效平均分
SELECT SId as 学生ID
,(SELECT score FROM SC WHERE SC.SId=t.SId AND CId='004') AS 数据库
,(SELECT score FROM SC WHERE SC.SId=t.SId AND CId='001') AS 企业管理
,(SELECT score FROM SC WHERE SC.SId=t.SId AND CId='006') AS 英语
,COUNT(*) AS 有效课程数, AVG(t.score) AS 平均成绩
FROM SC AS t
GROUP BY SId
ORDER BY avg(t.score)
18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
SELECT L.CId As 课程ID,L.score AS 最高分,R.score AS 最低分
FROM SC L ,SC AS R
WHERE L.CId = R.CId and
L.score = (SELECT MAX(IL.score)
FROM SC AS IL,Student AS IM
WHERE L.CId = IL.CId and IM.SId=IL.SId
GROUP BY IL.CId)
AND
R.Score = (SELECT MIN(IR.score)
FROM SC AS IR
WHERE R.CId = IR.CId
GROUP BY IR.CId
);
19、按各科平均成绩从低到高和及格率的百分数从高到低顺序
SELECT t.CId AS 课程号,max(course.Cname)AS 课程名,isnull(AVG(score),0) AS 平均成绩
,100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数
FROM SC T,Course
where t.CId=course.CId
GROUP BY t.CId
ORDER BY 100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) DESC
20、查询如下课程平均成绩和及格率的百分数(用"1行"显示): 企业管理(001),马克思(002),OO&UML (003),数据库(004)
SELECT SUM(CASE WHEN CId ='001' THEN score ELSE 0 END)/SUM(CASE CId WHEN '001' THEN 1 ELSE 0 END) AS 企业管理平均分
,100 * SUM(CASE WHEN CId = '001' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN CId = '001' THEN 1 ELSE 0 END) AS 企业管理及格百分数
,SUM(CASE WHEN CId = '002' THEN score ELSE 0 END)/SUM(CASE CId WHEN '002' THEN 1 ELSE 0 END) AS 马克思平均分
,100 * SUM(CASE WHEN CId = '002' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN CId = '002' THEN 1 ELSE 0 END) AS 马克思及格百分数
,SUM(CASE WHEN CId = '003' THEN score ELSE 0 END)/SUM(CASE CId WHEN '003' THEN 1 ELSE 0 END) AS UML平均分
,100 * SUM(CASE WHEN CId = '003' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN CId = '003' THEN 1 ELSE 0 END) AS UML及格百分数
,SUM(CASE WHEN CId = '004' THEN score ELSE 0 END)/SUM(CASE CId WHEN '004' THEN 1 ELSE 0 END) AS 数据库平均分
,100 * SUM(CASE WHEN CId = '004' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN CId = '004' THEN 1 ELSE 0 END) AS 数据库及格百分数
FROM SC
21、查询不同老师所教不同课程平均分从高到低显示
SELECT max(Z.TId) AS 教师ID,MAX(Z.Tname) AS 教师姓名,C.CId AS 课程ID,MAX(C.Cname) AS 课程名称,AVG(Score) AS 平均成绩
FROM SC AS T,Course AS C ,Teacher AS Z
where T.CId=C.CId and C.TId=Z.TId
GROUP BY C.CId
ORDER BY AVG(Score) DESC
22、查询如下课程成绩第 3 名到第 6 名的学生成绩单:企业管理(001),马克思(002),UML (003),数据库(004)
[学生ID],[学生姓名],企业管理,马克思,UML,数据库,平均成绩
SELECT DISTINCT top 3
SC.SId As 学生学号,
Student.Sname AS 学生姓名 ,
T1.score AS 企业管理,
T2.score AS 马克思,
T3.score AS UML,
T4.score AS 数据库,
ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0) as 总分
FROM Student,SC LEFT JOIN SC AS T1
ON SC.SId = T1.SId AND T1.CId = '001'
LEFT JOIN SC AS T2
ON SC.SId = T2.SId AND T2.CId = '002'
LEFT JOIN SC AS T3
ON SC.SId = T3.SId AND T3.CId = '003'
LEFT JOIN SC AS T4
ON SC.SId = T4.SId AND T4.CId = '004'
WHERE student.SId=SC.SId and
ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0)
NOT IN
(SELECT
DISTINCT
TOP 15 WITH TIES
ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0)
FROM sc
LEFT JOIN sc AS T1
ON sc.SId = T1.SId AND T1.CId = 'k1'
LEFT JOIN sc AS T2
ON sc.SId = T2.SId AND T2.CId = 'k2'
LEFT JOIN sc AS T3
ON sc.SId = T3.SId AND T3.CId = 'k3'
LEFT JOIN sc AS T4
ON sc.SId = T4.SId AND T4.CId = 'k4'
ORDER BY ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0) DESC);
23、统计列印各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60]
SELECT SC.CId as 课程ID, Cname as 课程名称
,SUM(CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS [100 - 85]
,SUM(CASE WHEN score BETWEEN 70 AND 85 THEN 1 ELSE 0 END) AS [85 - 70]
,SUM(CASE WHEN score BETWEEN 60 AND 70 THEN 1 ELSE 0 END) AS [70 - 60]
,SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS [60 -]
FROM SC,Course
where SC.CId=Course.CId
GROUP BY SC.CId,Cname;
24、查询学生平均成绩及其名次
SELECT 1+(SELECT COUNT( distinct 平均成绩)
FROM (SELECT SId,AVG(score) AS 平均成绩
FROM SC
GROUP BY SId
) AS T1
WHERE 平均成绩 > T2.平均成绩) as 名次,
SId as 学生学号,平均成绩
FROM (SELECT SId,AVG(score) 平均成绩
FROM SC
GROUP BY SId
) AS T2
ORDER BY 平均成绩 desc;
25、查询各科成绩前三名的记录:(不考虑成绩并列情况)
SELECT t1.SId as 学生ID,t1.CId as 课程ID,Score as 分数
FROM SC t1
WHERE score IN (SELECT TOP 3 score
FROM SC
WHERE t1.CId= CId
ORDER BY score DESC
)
ORDER BY t1.CId;
26、查询每门课程被选修的学生数
select cId,count(SId) from sc group by CId;
27、查询出只选修了一门课程的全部学生的学号和姓名
select SC.SId,Student.Sname,count(CId) AS 选课数
from SC ,Student
where SC.SId=Student.SId group by SC.SId ,Student.Sname having count(CId)=1;
28、查询男生、女生人数
Select count(Ssex) as 男生人数 from Student group by Ssex having Ssex='男';
Select count(Ssex) as 女生人数 from Student group by Ssex having Ssex='女';
29、查询姓“张”的学生名单
SELECT Sname FROM Student WHERE Sname like '张%';
30、查询同名同性学生名单,并统计同名人数
select Sname,count(*) from Student group by Sname having count(*)>1;;
31、1981年出生的学生名单(注:Student表中Sage列的类型是datetime)
select Sname, CONVERT(char (11),DATEPART(year,Sage)) as age
from student
where CONVERT(char(11),DATEPART(year,Sage))='1981';
32、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
Select CId,Avg(score) from SC group by CId order by Avg(score),CId DESC ;
33、查询平均成绩大于85的所有学生的学号、姓名和平均成绩
select Sname,SC.SId ,avg(score)
from Student,SC
where Student.SId=SC.SId group by SC.SId,Sname having avg(score)>85;
34、查询课程名称为“数据库”,且分数低于60的学生姓名和分数
Select Sname,isnull(score,0)
from Student,SC,Course
where SC.SId=Student.SId and SC.CId=Course.CId and Course.Cname='数据库'and score <60;
35、查询所有学生的选课情况;
SELECT SC.SId,SC.CId,Sname,Cname
FROM SC,Student,Course
where SC.SId=Student.SId and SC.CId=Course.CId ;
36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数;
SELECT distinct student.SId,student.Sname,SC.CId,SC.score
FROM student,Sc
WHERE SC.score>=70 AND SC.SId=student.SId;
37、查询不及格的课程,并按课程号从大到小排列
select cId from sc where scor e <60 order by CId ;
38、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名;
select SC.SId,Student.Sname from SC,Student where SC.SId=Student.SId and Score>80 and CId='003';
39、求选了课程的学生人数
select count(*) from sc;
40、查询选修“叶平”老师所授课程的学生中,成绩最高的学生姓名及其成绩
select Student.Sname,score
from Student,SC,Course C,Teacher
where Student.SId=SC.SId and SC.CId=C.CId and C.TId=Teacher.TId and Teacher.Tname='叶平' and SC.score=(select max(score)from SC where CId=C.CId );
41、查询各个课程及相应的选修人数
select count(*) from sc group by CId;
42、查询不同课程成绩相同的学生的学号、课程号、学生成绩
select distinct A.SId,B.score from SC A ,SC B where A.Score=B.Score and A.CId <>B.CId ;
43、查询每门功成绩最好的前两名
SELECT t1.SId as 学生ID,t1.CId as 课程ID,Score as 分数
FROM SC t1
WHERE score IN (SELECT TOP 2 score
FROM SC
WHERE t1.CId= CId
ORDER BY score DESC
)
ORDER BY t1.CId;
44、统计每门课程的学生选修人数(超过10人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,查询结果按人数降序排列,若人数相同,按课程号升序排列
select CId as 课程号,count(*) as 人数
from sc
group by CId
order by count(*) desc,cId
45、检索至少选修两门课程的学生学号
select SId
from sc
group by sId
having count(*) > = 2
46、查询全部学生都选修的课程的课程号和课程名
select CId,Cname
from Course
where CId in (select cId from sc group by cId)
47、查询没学过“叶平”老师讲授的任一门课程的学生姓名
select Sname from Student where SId not in (select SId from Course,Teacher,SC where Course.TId=Teacher.TId and SC.CId=course.CId and Tname='叶平');
48、查询两门以上不及格课程的同学的学号及其平均成绩
select SId,avg(isnull(score,0)) from SC where SId in (select SId from SC where score <60 group by SId having count(*)>2)group by SId;
49、检索“004”课程分数小于60,按分数降序排列的同学学号
select SId from SC where CId='004'and score <60 order by score desc;
50、删除“002”同学的“001”课程的成绩
delete from Sc where SId='001'and CId='001';
问题描述:
本题用到下面三个关系表:
CARD 借书卡。 CNO 卡号,NAME 姓名,CLASS 班级
BOOKS 图书。 BNO 书号,BNAME 书名,AUTHOR 作者,PRICE 单价,QUANTITY 库存册数
BORROW 借书记录。 CNO 借书卡号,BNO 书号,RDATE 还书日期
备注:限定每人每种书只能借一本;库存册数随借书、还书而改变。
要求实现如下15个处理:
1. 写出建立BORROW表的SQL语句,要求定义主码完整性约束和引用完整性约束。
2. 找出借书超过5本的读者,输出借书卡号及所借图书册数。
3. 查询借阅了"水浒"一书的读者,输出姓名及班级。
4. 查询过期未还图书,输出借阅者(卡号)、书号及还书日期。
5. 查询书名包括"网络"关键词的图书,输出书号、书名、作者。
6. 查询现有图书中价格最高的图书,输出书名及作者。
7. 查询当前借了"计算方法"但没有借"计算方法习题集"的读者,输出其借书卡号,并按卡号降序排序输出。
8. 将"C01"班同学所借图书的还期都延长一周。
9. 从BOOKS表中删除当前无人借阅的图书记录。
10.如果经常按书名查询图书信息,请建立合适的索引。
11.在BORROW表上建立一个触发器,完成如下功能:如果读者借阅的书名是"数据库技术及应用",就将该读者的借阅记录保存在BORROW_SAVE表中(注ORROW_SAVE表结构同BORROW表)。
12.建立一个视图,显示"力01"班学生的借书信息(只要求显示姓名和书名)。
13.查询当前同时借有"计算方法"和"组合数学"两本书的读者,输出其借书卡号,并按卡号升序排序输出。
14.假定在建BOOKS表时没有定义主码,写出为BOOKS表追加定义主码的语句。
15.对CARD表做如下修改:
a. 将NAME最大列宽增加到10个字符(假定原为6个字符)。
b. 为该表增加1列NAME(系名),可变长,最大20个字符。
1. 写出建立BORROW表的SQL语句,要求定义主码完整性约束和引用完整性约束
--实现代码:
CREATE TABLE BORROW(
CNO int FOREIGN KEY REFERENCES CARD(CNO),
BNO int FOREIGN KEY REFERENCES BOOKS(BNO),
RDATE datetime,
PRIMARY KEY(CNO,BNO))
2. 找出借书超过5本的读者,输出借书卡号及所借图书册数
--实现代码:
SELECT CNO,借图书册数=COUNT(*)
FROM BORROW
GROUP BY CNO
HAVING COUNT(*)>5
3. 查询借阅了"水浒"一书的读者,输出姓名及班级
--实现代码:
SELECT * FROM CARD c
WHERE EXISTS(
SELECT * FROM BORROW a,BOOKS b
WHERE a.BNO=b.BNO
AND b.BNAME=N'水浒'
AND a.CNO=c.CNO)
4. 查询过期未还图书,输出借阅者(卡号)、书号及还书日期
--实现代码:
SELECT * FROM BORROW
WHERE RDATE
5. 查询书名包括"网络"关键词的图书,输出书号、书名、作者
--实现代码:
SELECT BNO,BNAME,AUTHOR FROM BOOKS
WHERE BNAME LIKE N'%网络%'
6. 查询现有图书中价格最高的图书,输出书名及作者
--实现代码:
SELECT BNO,BNAME,AUTHOR FROM BOOKS
WHERE PRICE=(
SELECT MAX(PRICE) FROM BOOKS)
7. 查询当前借了"计算方法"但没有借"计算方法习题集"的读者,输出其借书卡号,并按卡号降序排序输出
--实现代码:
SELECT a.CNO
FROM BORROW a,BOOKS b
WHERE a.BNO=b.BNO AND b.BNAME=N'计算方法'
AND NOT EXISTS(
SELECT * FROM BORROW aa,BOOKS bb
WHERE aa.BNO=bb.BNO
AND bb.BNAME=N'计算方法习题集'
AND aa.CNO=a.CNO)
ORDER BY a.CNO DESC
8. 将"C01"班同学所借图书的还期都延长一周
--实现代码:
UPDATE b SET RDATE=DATEADD(Day,7,b.RDATE)
FROM CARD a,BORROW b
WHERE a.CNO=b.CNO
AND a.CLASS=N'C01'
9. 从BOOKS表中删除当前无人借阅的图书记录
--实现代码:
DELETE A FROM BOOKS a
WHERE NOT EXISTS(
SELECT * FROM BORROW
WHERE BNO=a.BNO)
10. 如果经常按书名查询图书信息,请建立合适的索引
--实现代码:
CREATE CLUSTERED INDEX IDX_BOOKS_BNAME ON BOOKS(BNAME)
11. 在BORROW表上建立一个触发器,完成如下功能:如果读者借阅的书名是"数据库技术及应用",就将该读者的借阅记录保存在BORROW_SAVE表中(注ORROW_SAVE表结构同BORROW表)
--实现代码:
CREATE TRIGGER TR_SAVE ON BORROW
FOR INSERT,UPDATE
AS
IF @@ROWCOUNT>0
INSERT BORROW_SAVE SELECT i.*
FROM INSERTED i,BOOKS b
WHERE i.BNO=b.BNO
AND b.BNAME=N'数据库技术及应用'
12. 建立一个视图,显示"力01"班学生的借书信息(只要求显示姓名和书名)
--实现代码:
CREATE VIEW V_VIEW
AS
SELECT a.NAME,b.BNAME
FROM BORROW ab,CARD a,BOOKS b
WHERE ab.CNO=a.CNO
AND ab.BNO=b.BNO
AND a.CLASS=N'力01'
13. 查询当前同时借有"计算方法"和"组合数学"两本书的读者,输出其借书卡号,并按卡号升序排序输出
--实现代码:
SELECT a.CNO
FROM BORROW a,BOOKS b
WHERE a.BNO=b.BNO
AND b.BNAME IN(N'计算方法',N'组合数学')
GROUP BY a.CNO
HAVING COUNT(*)=2
ORDER BY a.CNO DESC
14. 假定在建BOOKS表时没有定义主码,写出为BOOKS表追加定义主码的语句
--实现代码:
ALTER TABLE BOOKS ADD PRIMARY KEY(BNO)
15.1 将NAME最大列宽增加到10个字符(假定原为6个字符)
--实现代码:
ALTER TABLE CARD ALTER COLUMN NAME varchar(10)
15.2 为该表增加1列NAME(系名),可变长,最大20个字符
--实现代码:
ALTER TABLE CARD ADD 系名 varchar(20)
问题描述:
为管理岗位业务培训信息,建立3个表:
S (SId,SN,SD,SA) SId,SN,SD,SA 分别代表学号、学员姓名、所属单位、学员年龄
C (CId,CN ) CId,CN 分别代表课程编号、课程名称
SC ( SId,CId,G ) SId,CId,G 分别代表学号、所选修的课程编号、学习成绩
要求实现如下5个处理:
1. 使用标准SQL嵌套语句查询选修课程名称为’税收基础’的学员学号和姓名
2. 使用标准SQL嵌套语句查询选修课程编号为’C2’的学员姓名和所属单位
3. 使用标准SQL嵌套语句查询不选修课程编号为’C5’的学员姓名和所属单位
4. 使用标准SQL嵌套语句查询选修全部课程的学员姓名和所属单位
5. 查询选修了课程的学员人数
6. 查询选修课程超过5门的学员学号和所属单位
1. 使用标准SQL嵌套语句查询选修课程名称为’税收基础’的学员学号和姓名
--实现代码:
SELECT SN,SD FROM S
WHERE [SId] IN(
SELECT [SId] FROM C,SC
WHERE C.[CId]=SC.[CId]
AND CN=N'税收基础')
2. 使用标准SQL嵌套语句查询选修课程编号为’C2’的学员姓名和所属单位
--实现代码:
SELECT S.SN,S.SD FROM S,SC
WHERE S.[SId]=SC.[SId]
AND SC.[CId]='C2'
3. 使用标准SQL嵌套语句查询不选修课程编号为’C5’的学员姓名和所属单位
--实现代码:
SELECT SN,SD FROM S
WHERE [SId] NOT IN(
SELECT [SId] FROM SC
WHERE [CId]='C5')
4. 使用标准SQL嵌套语句查询选修全部课程的学员姓名和所属单位
--实现代码:
SELECT SN,SD FROM S
WHERE [SId] IN(
SELECT [SId] FROM SC
RIGHT JOIN C ON SC.[CId]=C.[CId]
GROUP BY [SId]
HAVING COUNT(*)=COUNT(DISTINCT [SId]))
5. 查询选修了课程的学员人数
--实现代码:
SELECT 学员人数=COUNT(DISTINCT [SId]) FROM SC
6. 查询选修课程超过5门的学员学号和所属单位
--实现代码:
SELECT SN,SD FROM S
WHERE [SId] IN(
SELECT [SId] FROM SC
GROUP BY [SId]
HAVING COUNT(DISTINCT [CId])>5)