面试题汇总(二)


面试题汇总, 答案大部分来自于网上+自己的理解,整合了一下。留作标记,以后常来看看~如果有错,欢迎指出~

一、   选择题(每小题4分,少选得两分)

1.   表达式(15/2^2)的值是   (A)

A. 5

B. 15

C. 14

D. 0

解析:15/2为7.5,取整7,异或2,化成二进制为111异或010得到结果101,然后化成十进制为5

 

1.十进制转化为2进制:除2取余倒着排

2.异或:相同输出0,不同输出1

3.运算符相关知识:

运算符指明对操作数的运算方式。组成表达式的Java操作符有很多种。运算符按照其要求的操作数数目来分,可以有单目运算符双目运算符和三目运算符,它们分别对应于1个、2个、3个操作数。运算符按其功能来分,有算术运算符赋值运算符关系运算符逻辑运算符位运算符和其他运算符。[1]

算术

单目:+(取正)-(取负) ++(自增1 - -(自减1

双目:+ - * / %(取余)

三目:a>b?true:false 说明:当a大于b的时候,为true(也就是冒号之前的值),否则为false;这整个运算符包括一个关系运算符(可以是“>”"<""!="等等),一个,一个,冒号前后需要有两个表达式或者是值或者是对象。

关系

等于符号:==,不等于符号:!= ,大于符号:>小于符号:<,大于等于符号:>= ,小于等于符号:<=

位与逻辑

运算符 与(&)、非(~)、或(|)、异或(^

&:双目运算符,运算时均把运算数转换为二进制再做比较,规则:当相同的位上均为1时结果为1,否则结果为0.如:1010&1101,转为二进制:10001001101&1111110010比较结果为:1000000转为十进制: 64所以1010&1101=64

| :当两边操作数的位有一边为1时,结果为1,否则为0。如1100|1010=1110

~01,10

^:两边的位不同时,结果为1,否则为0.1100^1010=0110

逻辑运算符

与(&&)、非(!)、或(||

赋值

= += -= *= /= %= &= ^= |= <<= >>=

instanceof

运算符双目运算符,左面的操作元是一个对象,右面是一个类。当左面的对象是右面的类创建的对象时,该运算符运算结果是true,否则是false

运算符综述

Java 表达式就是用运算符连接起来的符合Java 规则的式子.运算符的优先级决定了表达式中运算执行的先后顺序.例如,x<y&&!z相当于(x<y)&&(!z),没有必要去记忆运算符号的优先级别,在编写程序时可尽量的使用括号来实现你想要的运算次序,以免产生难以阅读或含糊不清的计算顺序.运算符的结合性决定了并列相同级别的运算符的先后顺序,例如,加减的结合性是从左到右,8-5+3 相当于(8-5)+3.逻辑否运算符的结合性是右到左, x 相当于!(!x).3.4Java所有运算符的优先级和结合性。

位移

<< 带符号左移 >>带符号右移 >>> 无号右移

运算符优先级

优先级从高到低排列如下:[ ] ( ) ++ -- ! instanceof * / % + - << >> >>> <> < = > \ == != &^& & || ? := op=

 

运算符操作

一、运算符"+",如果必要则自动把操作数转换为String型。如果操作数是一个对象,它可定义一个方法toString()返回该对象的String方式,例如floata=1.0print(“Thevalueofais”+a+“\n”);+运算符用到的例子Strings=“a=”+a;+=运算符也可以用于String。注意,左边(下例中的s1)仅求值一次。s1+=a;//s1=s1+a//aString型,自动转换为String型。

二、整数算术运算的异常是由于除零或按零取模造成的。它将引发一个算术异常。下溢产生零,上溢导致越界。例如:加1超过整数最大值,取模后,变成最小值。一个op=赋值运算符,和上表中的各双目整数运算符联用,构成一个表达式。整数关系运算符<><=>===!=产生boolean类型的数据。

三、数组运算符数组运算符形式如下:<expression>[<expression>]可给出数组中某个元素的值。合法的取值范围是从0数组的长度减1

四、对象运算符双目运算符instanceof测试某个对象是否是指定类或其子类的实例。例如:if(myObjectinstanceofMyClass){MyClassanothermyObject=(MyClass)myObject;…}是判定myObject是否是MyClass的实例或是其子类的实例。

五、浮点运算符浮点运算符可以使用常规运算符的组合:如单目运算符++--双目运算符+-*/,以及赋值运算符+=-=*=,和/=。此外,还有取模运算%%=也可以作用于浮点数,例如:a%ba-((int)(a/b)*b)的语义相同。这表示a%b的结果是除完后剩下的浮点数部分。只有单精度操作数的浮点表达式按照单精度运算求值,产生单精度结果。如果浮点表达式中含有一个或一个以上的双精度操作数,则按双精度运算,结果是双精度浮点数

六、布尔运算符布尔(boolean)变量表达式的组合运算可以产生新的boolean值,falestrue(记得是小写)。单目运算符!布尔非。双目运算符&|^是逻辑ANDORXOR运算符,它们强制两个操作数布尔值。为避免右侧操作数冗余求值,用户可以使用短路求值运算符&&||

七、用户可以使用==!=赋值运算符也可以用&=|=^=。三元条件操作符和C语言中的一样。

八、++运算符用于表示直接加1操作。增量操作也可以用加运算符和赋值操作间接完成。++lvalue左值表示lvalue+=1,++lvalue也表示lvalue=lvalue+1

九、--运算符用于表示减1操作。++--运算符既可以作为前缀运算符,也可以做为后缀运算符。双目整数运算符是:运算符操作**+-*/%取模&位与|位或^位异或<<左移 >>右移(带符号) >>>添零右移整数除法按零舍入。除法和取模遵守以下等式:

(a/b)*b+(a%b)==a

java运算符

&是位

&&是逻辑

&两边是整数时执行的是位运算,而两边是boolean值时执行的是逻辑运算,

:

3&6 就是执行的位运算,结果是一个整数:2

true&false 执行的就是逻辑运算,结果是一个boolean:false

&的逻辑运算和&&逻辑运算是存在一定不同的

&逻辑运算时两边都会计算的,而&&则在左边为假时则直接返的是false不再计算右边

举个例子:

1:

int[] a={1,2,3};

if(a[0]==2&a[3]==4){System.out.println("true")}

2:

int[] a={1,2,3};

if(a[0]==2&&a[3]==4){System.out.println("true")}

这两个例子中,第一个会抛出异常,而第二个则什么不会输出也不会抛异常

这是因为第一个例子中if语句中用的是&,所以两边的都会计算,当计算a[3]==4时抛出数组下标越界异常

第二个例子则在计算第一个式子a[0]==2发现结果为假则不再计算右边,直接返回false,所以该例子不会输出任何东西

3java中用的最多的一个三目运算符A=3?b:c;

如果A=3成立的话结果是b,如果不成立的话结果是c;

运算符演示

Java 中提供运算功能的就是运算符(Operator),算术运算符有加(+)、减(-)、乘(*)、除(/)这类的运算符。另外还有一个很常用的取模运算(%)。这类以数学运算为主的运算符称为算术运算符(Arithmetic Operator)

举几个算数运算的例子:

int a = 5+4 //a=9

int b = a*2 //b=18

int c = b/4 //c=4

int d = b-c //d=14

int e = -d //e=-14

int f = e%4 //f=-2

这里简单说一下取模运算(%),其实就是取除法后的余数,例子中的int f = e%4,就是-144取余数,结果为-2。与C C++不同,对取模运算%来说,其操作数可以为浮点数, 37.2%10=7.2

而且,Java对加运算符进行了扩展,使它能够进行字符串的连接,如"abc"+"de",得到字符串 "abcde"。但是这只是对于字符串连接的简单扩展,字符串并不支持诸如减法的其他运算。有趣的是,字符是支持加法和减法的,其参与运算的是这个字符的ASCII码值。例如bASCII码值比a1,所以(‘b’-‘a’)的结果就是1

三个移位

JAVA左移:<<带符号右移:>>

无符号右移:>>>“ < <”, “> > ”, “> > > ”Java中是左移、有符号右移和无符号右移运算符。位移运算符只对int值进行操作,如果不是int编译器会报错。在Java中,一个int的长度始终是32bit,也就是4字节

1)左移动运算符

会将操作的数向左边移动,移动的位的个数由指定,左移(2)右移动运算符

反过来,把操作数向右移动,移动的位个数同样由右操作数指定。(3)无正负号的右移运算符(>>>)

采用0补充,意思就是说

Test { main(String[] args) {

m=-7;

System.out.println("m的二制码是:"+Integer.toBinaryString(m));

System.out.println("m>>2的二进制码是:"+Integer.toBinaryString(m>>2));

System.out.println("(m>>2)="+(m>>2));

System.out.println("m<<2的二进制码是:"+Integer.toBinaryString(m<<2));

System.out.println("(m<<2)=:"+(m<<2));

System.out.println("m>>>24的二进制码是:"+Integer.toBinaryString(m>>>24));

System.out.println(" m>>>24 :"+ (m>>>24));

}

}

-7的反码:11111111111111111111111111111000

补码:11111111111111111111111111111001

 

 

2.    下列对final修饰符的描述,正确的有  (AD)

      A. 被final修饰的class不能被继承

B. 被final修饰的方法不能被重载(Overload)

C. 被final修饰的变量只能在变量定义时初始化   构造方法

D. final不能用于修饰构造方法

解析:重写是子类的方法覆盖父类的方法,要求方法名和参数都相同

重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同,最常见的重载的例子就是类的构造函数,可以参考API帮助文档看看类的构造方法

 

final可用来修饰类,变量,方法。

 1.final修饰变量:final修饰变量时,表示该变量一旦获得了初始值之后就不可改变。

 1.修饰成员变量:与普通成员变量不同的是,final成员变量(实例属性和类属性)必须由程序员显示初始化,系统不会对final成员变量进行隐式初始化。

 final修饰的成员变量初始化过程:当进行静态初始化时,可对类属性初始化,当执行普通初始化块,构造器时可对实例属性初始化,因此:非final成员变量的初始值,可以在定义该变量时指定初始值,可以在初始化块,构造器中执行初始化值,否则成员变量的初始值是由系统自动分配的初始值。

final修饰的类属性,实例属性指定初始值的地方:

类属性:静态初始化块,声明该属性时指定初始值。

实例属性:非静态初始化块,构造器,声明该属性时指定初始化值。

2.final修饰局部变量:

1.系统不会对局部变量进行初始化,必须由程序员显示初始化。

如果在定义final变量时没有指定初始值,则可以在后面代码中进行对final变量赋初始值,但只能一次,不能重复赋值,,如果final修饰的局部变量在定义时已经指定默认值,则后面的代码中不能再对该变量赋值。

2.final修饰形参不能被赋值,因为形参在调用该方法时,有系统传入的参数来完成初始化。

3.final修饰基本类型变量与引用类型变量的区别:

1.final修饰基本类型变量时,不能对基本变量重新赋值,因为基本类型变量不能被改变。

2.final修饰引用类型变量时,仅仅保持的是这个引用所引用的地址不会改变,既一直引用同一个对象。但这个对象完全可以改变(对象的属性)

                                       例如: final person p = new person();

                                                 //改变person对象的age属性,合法。

                                                 p.SetAge(23);

                                                 //p引用重新赋值,不合法。

                                                  p = null;

          注意:如果final修饰变量是基本数据类型,且在编译时就可以确定该变量的值,于是把该变量当做常量来处理:常量命名规则:多个有意义的单词连接,所有字符大写,单词之间用下划线分割。

        如果final修饰变量是引用类型,final变量无法在编译时就获得值,而必须在运行时才能得到值如:final  TestClass t = new TestClass();编译时系统不会创建一个TestClass对象赋给 t 变量,所以t不需要当做常量来处理,无需使用常量命名规则。

4.final方法:

1.final修饰的方法不可被重写。

2.java提供的Object类有一个final方法:getClass(),因为java不希望任何一个类重写这个方法。

3.对于private 方法,仅在当前类中可见,子类无法访问,所以也就无法重写该方法,如果子类中定义了一个与父类private方法有相同方法名,相同形参列表,相同返回值类项的方法,也不是方法重写,只是重新定义了一个方法,因此使用final修饰的一个private 访问权限的方法,依然可以在其子类中定义与该方法有相同方法名,相同形参列表,相同返回值类型的方法。

4.final修饰的方法不能被重写但完全可以被重载。

5.final类:

1.final修饰的类不可有子类,java.lang.Math类就是一个final类,它不可以有子类。

 

 

3.  下列对static修饰符的描述,正确的有  (BD)

      A. static不能作为class的修饰符   

B. 被static修饰的成员变量和成员方法独立于该类的任何对象

C. 被static修饰的成员(类、方法、成员变量)不能再使用private进行修饰

D. static代码块(静态代码块),在类的构造函数之前被执行

解析:static可以修饰内部类,普通类不行;执行顺序:static代码块,普通代码块,构造函数;static成员变量和static成员方法都可以使用private进行修饰

static 修饰符可以用来修饰类的成员变量,成员方法和代码块。 
       
static 修饰的成员变量表示静态变量,可以直接通过类来访问。 
       
static 修饰的成员方法表示静态方法,可以直接通过类名来访问。 
       
static 修饰的程序代码块表示静态代码块,当JAVA虚拟机加载类时,就会执行该代码块。 
       
static 所修饰的成员变量和成员方法标明归某个类所有,它不依赖于类的特定实例,被类的所有实例共享。只要这个类被加载,JAVA虚拟机就能根据类名在运行时数据区的方法区定位到它们。 

     static
变量 
    
类的成员变量有两种,一个是实例变量,没有被 static 修饰,一种是被 static 修饰过的变量,叫类变量或者静态变量。 

    
静态变量和实例变量的区别:  
     静态变量在内存中只有一个拷贝,运行时JAVA虚拟机只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存分配。可以直接通过类名访问静态变量。 
    
对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响。 

      static
方法 
     
成员方法分为静态方法和实例方法。用 static 修饰的方法叫做静态方法,或者类方法。静态方法和静态变量一样,不需要创建类的实例,可以直接通过类名来访问。 

     
因为静态方法不需要通过它所属的类的任何实例就会被调用,因此在静态方法中不能使用 this 关键字,也不能直接访问所属类的实例变量和实例方法,但是可以直接访问所属类的静态变量和静态方法。

class StaticTest{   
  
        static int num =100;   
        int num1 = 20;   
  
        static void staticMethod(){   
           System.out.println("StaticMethod!");   
           //System.out.println(this.num); //编译错误,在static 方法内,不能使用this 关键字   
              //System.out.println(this.num1);//编译错误,在static 方法内,不能使用this 关键字   
             //   System.out.println(num1);//编译错误,在static 方法内,不能直接访问非 static 变量或者方法   
  
            System.out.println(StaticTest.num);   
        }   
               
          void LocalMethod(){   
                       System.out.println("StaticMethod!");   
           }   
  
                      
  
              public static void main(String args[]){   
                       StaticTest t = new StaticTest();   
  
                       //静态变量被所有的实例共享   
                          t.staticMethod();   
                       System.out.println(t.num);   
                       StaticTest.staticMethod();   
                       System.out.println(StaticTest.num);   
                   }   
        }   
  
      //  总结:在静态方法内不允许访问非静态变量不能出现 this supper   
static 代码块 
      类中可以包含静态代码块,它不存在于任何方法体中。在JAVA虚拟机加载类时会执行这些静态代码块。如果类中包含多个静态块,那么JAVA虚拟机将按照他们在类中出现的顺序依次执行它,并且每个代码块只会被执行一次。

class StaticBlock{   
  
             static int i =5;   
             int j;   
             static{   
                      System.out.println("First :"+i++);   
                  }   
  
             static{   
                      System.out.println("Sencond :" +i++);   
                  }   
                   
             public static void main(String args[]){   
                      StaticBlock s1 = new StaticBlock();   
                      StaticBlock s2 = new StaticBlock();   
                      System.out.println("Last :"+i);   
                  }   
       } 

静态方法必须被实现 
     
静态方法用来表示某个类所特有的功能,这种功能的实现不依赖于类的具体实例,也不依赖于它的子类。既然如此,当前类必须为静态方法提供实现,即一个静态的方法不  能被定义为抽象方法。 

      static
abstract 永远不能放在一起用 

     
如果一个方法是静态的,它就必须自力更生,自己实现该方法。 (引申为接口的方法也不能为static)
     
如果一个方法是抽象的,那么它就只表示类所具有的功能,但不会去实现它,在子类中才会去实现它。 

       
作为程序入口的 main() 方法是静态方法 

       
因为把 main() 方法定义为静态方法,可以使得JAVA虚拟机只要加载了 main 方法所属的类,就能执行 main() 方法,而无须创建这个类的实例。 

       
main() 方法中不能直接访问实例变量和实例方法

 

 

4. 下列的网络协议中,面向连接的的协议是  (B)

      A. 用户数据报协议 UDP

B. 传输控制协议  TCP

C. 网际协议  IP

D. 网际控制报文协议 ICMP

解析

TCP/IP协议介绍 
  
TCP/IP通讯协议 
  
  这部分简要介绍一下TCP/IP的内部结构,为讨论与互联网有关的安全问题打下基础。TCP/IP协议组之所以流行,部分原因是因为它可以用在各种各样的信道和底层协议(例如T1X.25、以太网以及RS-232串行接口)之上。确切地说,TCP/IP协议是一组包括TCP协议和IP协议,UDPUser Datagram Protocol)协议、ICMPInternet Control Message Protocol)协议和其他一些协议的协议组。 
  
TCP/IP整体构架概述 
  
TCP/IP协议并不完全符合OSI的七层参考模型。传统的开放式系统互连参考模型,是一种通信协议7层抽象的参考模型,其中每一层执行某一特定任务。该模型的目的是使各种硬件在相同的层次上相互通信。这7层是:物理层数据链路层、网路层、传输层、话路层、表示层应用层。而TCP/IP通讯协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。这4层分别为: 
  
  应用层:应用程序间沟通的层,如简单电子邮件传输(SMTP)、文件传输协议FTP)、网络远程访问协议(Telnet)等。 
  
  传输层:在此层中,它提供了节点间的数据传送服务,如传输控制协议(TCP、用户数据报协议(UDP)等,TCPUDP给数据包加入传输数据并把它传输到下一层中,这一层负责传送数据,并且确定数据已被送达并接收。 
  
  互连网络层:负责提供基本的数据封包传送功能,让每一块数据包都能够到达目的主机(但不检查是否被正确接收),如网际协议(IP)。 
  
  网络接口层:对实际的网络媒体的管理,定义如何使用实际网络(如EthernetSerial Line等)来传送数据。 
  
TCP/IP中的协议 
  
  以下简单介绍TCP/IP中的协议都具备什么样的功能,都是如何工作的:

 

1 IP 
  
  网际协议IPTCP/IP的心脏,也是网络层中最重要的协议。 
  
IP层接收由更低层(网络接口层例如以太网设备驱动程序)发来的数据包,并把该数据包发送到更高层---TCPUDP层;相反,IP层也把从TCPUDP层接收来的数据包传送到更低层。IP数据包是不可靠的,因为IP并没有做任何事情来确认数据包是按顺序发送的或者没有被破坏。IP数据包中含有发送它的主机的地址(源地址)和接收它的主机的地址(目的地址)。 
  
  高层的TCPUDP服务在接收数据包时,通常假设包中的源地址是有效的。也可以这样说,IP地址形成了许多服务的认证基础,这些服务相信数据包是从一个有效的主机发送来的。IP确认包含一个选项,叫作IP source routing,可以用来指定一条源地址和目的地址之间的直接路径。对于一些TCPUDP的服务来说,使用了该选项的IP包好象是从路径上的最后一个系统传递过来的,而不是来自于它的真实地点。这个选项是为了测试而存在的,说明了它可以被用来欺骗系统来进行平常是被禁止的连接。那么,许多依靠IP源地址做确认的服务将产生问题并且会被非法入侵

 

2. TCP 
  
  如果IP数据包中有已经封好的TCP数据包,那么IP将把它们向传送到TCP层。TCP将包排序并进行错误检查,同时实现虚电路间的连接。TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。 
  
TCP将它的信息送到更高层的应用程序,例如Telnet的服务程序和客户程序。应用程序轮流将信息送回TCP层,TCP层便将它们向下传送到IP层,设备驱动程序和物理介质,最后到接收方。 
  
  面向连接的服务(例如TelnetFTPrloginX WindowsSMTP)需要高度的可靠性,所以它们使用了TCPDNS在某些情况下使用TCP(发送和接收域名数据库),但使用UDP传送有关单个主机的信息。

 

3.UDP 
  
UDPTCP位于同一层,但对于数据包的顺序错误或重发。因此,UDP不被应用于那些使用虚电路的面向连接的服务,UDP主要用于那些面向查询---应答的服务,例如NFS。相对于FTPTelnet,这些服务需要交换的信息量较小。使用UDP的服务包括NTP(网落时间协议)和DNSDNS也使用TCP)。 
  
  欺骗UDP包比欺骗TCP包更容易,因为UDP没有建立初始化连接(也可以称为握手)(因为在两个系统间没有虚电路),也就是说,与UDP相关的服务面临着更大的危险。

 

4.ICMP 
  
ICMPIP位于同一层,它被用来传送IP的的控制信息。它主要是用来提供有关通向目的地址的路径信息。ICMP‘Redirect’信息通知主机通向其他系统的更准确的路径,而‘Unreachable’信息则指出路径有问题。另外,如果路径不可用了,ICMP可以使TCP连接体面地终止。PING是最常用的基于ICMP的服务。
 
5. TCPUDP的端口结构 
  
TCPUDP服务通常有一个客户/服务器的关系,例如,一个Telnet服务进程开始在系统上处于空闲状态,等待着连接。用户使用Telnet客户程序与服务进程建立一个连接。客户程序向服务进程写入信息,服务进程读出信息并发出响应,客户程序读出响应并向用户报告。因而,这个连接是双工的,可以用来进行读写。

  两个系统间的多重Telnet连接是如何相互确认并协调一致呢?TCPUDP连接唯一地使用每个信息中的如下四项进行确认: 
  
  IP地址发送包的IP地址。 
  
  目的IP地址接收包的IP地址。 
  
  源端口源系统上的连接的端口。 
  
  目的端口目的系统上的连接的端口。 
  
  端口是一个软件结构,被客户程序或服务进程用来发送和接收信息。一个端口对应一个16比特的数。服务进程通常使用一个固定的端口,例如,SMTP使用25Xwindows使用6000。这些端口号广为人知的,因为在建立与特定的主机或服务的连接时,需要这些地址和目的地址进行通讯。
 
http://blog.chinaunix.net/uid-26833883-id-3627644.html

 

 

5.在linux系统中能解压test.Z压缩文件的命令是  D

      A. tar

B. ungzip

C. compress

D. uncompress

解析

 

linux下解压命令大全

 

.tar

解包:tar xvf FileName.tar

打包:tar cvf FileName.tar DirName

(注:tar是打包,不是压缩!)

———————————————

.gz

解压1:gunzip FileName.gz

解压2:gzip -d FileName.gz

压缩:gzip FileName

 

.tar.gz 和 .tgz

解压:tar zxvf FileName.tar.gz

压缩:tar zcvf FileName.tar.gz DirName

———————————————

.bz2

解压1:bzip2 -d FileName.bz2

解压2:bunzip2 FileName.bz2

压缩: bzip2 -z FileName

 

.tar.bz2

解压:tar jxvf FileName.tar.bz2

压缩:tar jcvf FileName.tar.bz2 DirName

———————————————

.bz

解压1:bzip2 -d FileName.bz

解压2:bunzip2 FileName.bz

压缩:未知

 

.tar.bz

解压:tar jxvf FileName.tar.bz

压缩:未知

———————————————

.Z

解压:uncompress FileName.Z

压缩:compress FileName

.tar.Z

 

解压:tar Zxvf FileName.tar.Z

压缩:tar Zcvf FileName.tar.Z DirName

———————————————

.zip

解压:unzip FileName.zip

压缩:zip FileName.zip DirName

———————————————

.rar

解压:rar x FileName.rar

压缩:rar a FileName.rar DirName

———————————————

.lha

解压:lha -e FileName.lha

压缩:lha -a FileName.lha FileName

———————————————

.rpm

解包:rpm2cpio FileName.rpm | cpio -div

———————————————

.deb

解包:ar p FileName.deb data.tar.gz | tar zxf -

———————————————

.tar .tgz .tar.gz .tar.Z .tar.bz .tar.bz2 .zip .cpio .rpm .deb .slp .arj .rar .ace .lha .lzh .lzx .lzs .arc .sda .sfx .lnx .zoo .cab .kar .cpt .pit .sit .sea

解压:sEx x FileName.*

压缩:sEx a FileName.* FileName

 

sEx只是调用相关程序,本身并无压缩、解压功能,请注意!

 

gzip 命令

减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。gzip 是在 Linux 系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用。

 

语法:gzip [选项] 压缩(解压缩)的文件名该命令的各选项含义如下:

 

-c 将输出写到标准输出上,并保留原有文件。-d 将压缩文件解压。-l 对每个压缩文件,显示下列字段:     压缩文件的大小;未压缩文件的大小;压缩比;未压缩文件的名字-r 递归式地查找指定目录并压缩其中的所有文件或者是解压缩。-t 测试,检查压缩文件是否完整。-v 对每一个压缩和解压的文件,显示文件名和压缩比。-num 用指定的数字 num 调整压缩的速度,-1 或 --fast 表示最快压缩方法(低压缩比),-9 或--best表示最慢压缩方法(高压缩比)。系统缺省值为 6。指令实例:

 

gzip *% 把当前目录下的每个文件压缩成 .gz 文件。gzip -dv *% 把当前目录下每个压缩的文件解压,并列出详细的信息。gzip -l *% 详细显示例1中每个压缩的文件的信息,并不解压。gzip usr.tar% 压缩 tar 备份文件 usr.tar,此时压缩文件的扩展名为.tar.gz。

 

6.下列对TCP协议的描述正确的有(AB)

      A. TCP协议能保证可靠传输

B. TCP协议建立连接需要进行3次握手

C. TCP协议释放连接需要进行3次握手  

D. TCP协议是一个应用层协议  传输层

解析:建立连接需要3次握手,结束需要4次握手;可靠传输

7.下列对变量的定于语句中合法的有 (AD)

A. char c = '我'

B. String str = '我'

C. byte b = 128

D. float f = 1

 

8.下列操作属于DDL的有   (B)

      A. select

B. drop

C. insert

D. update

E. alert.

解析:create drop  alter 都属于DDL操作

9.以下数据结构中不属于线性数据结构的是  (C)

线性表和链表之外其他的都不属于线性数据结构  

      A. 队列

B. 线性表

C. 二叉树

D. 栈

 

10.下列对JSP中forward 和redirect的描述正确的有  (AC)

      A.forward操作不会在用户浏览器里展现跳转地址

B. redirect操作不会在用户浏览器里展现跳转地址

C.forward操作会把原始请求数据转发给跳转地址

D. redirect操作会把原始请求数据转发给跳转地址

解析:

forward内部跳转redirect重定向跳转的区别
1.从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
  
2.数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据.
  
3.从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.
  
4.从效率来说
forward:.
redirect:.

 

 

 

二、   简单题(20分)

1.  请列举至少3个JDK安装目录下的可执行程序(如javac),并列举几个常用的命令行参数。(6分)

 

java  -version

javac  -classpath -sourcepath  -version

javadoc

jar

jdb  用来debug

 

2.  请分析命题:“Java采用自动垃圾回收技术(GC) ,因此不会出现内存泄露”。(6分)

我认为此命题是错误的。内存泄漏指你用new申请了一块内存,但是没有将内存释放,导致这块内存一直处于占用状态

java有垃圾回收机制自动管理内存的回收。因此开发人员不需要调用方法来释放内存。但是不表明java就不会出现内存泄露,有些情况也会导致java编写的程序出现内存泄露的问题。

举例说明:

 

Vector v = newVector(10);

for (int i = 1;i<100; i++){

   Object o = new Object();

   v.add(o);

   o = null;

}

o对象是不能被回收的,因为实际上v引用了这些对象,还被引用的对象GC是没有办法回收的,这样就很可能导致内存的泄露。

 

3.  请简单描述单子模式(单例模式)的几种不同实现方式,及各自优缺点。请列举至少2种其他的设计模式及应用场景。(8分)

 

工厂模式,实例化对象;适配器模式等

(1)

/* 线程安全 但效率比较低  一开始就要加载类new一个 对象

这是饿汉方式的单例模式*/

 

public class Singleton1 {

            private Singleton1(){

            }

            private static finalSingleton1 instance=newSingleton1();

            public static Singleton1 getInstancei(){

                        return instance;

            }

}

 

(2)

// 饱汉方式的单例模式 但是有多个线程访问时就不是安全的 返回的不是同一个对象

public class Singleton {

            private Singleton(){

            }

            private static Singleton instance;

            public static Singleton getInstance() {

                        if (instance == null)

                                    instance= new Singleton();

                        return instance;

            }

}

(3)

//虽然是安全的 但是效率非常低在一个时候只有一个线程能访问  同时返回一个对象

public class Singleton2 {

            private Singleton2(){

            }

            private static Singleton2 instance;

            public static synchronizedSingleton2 getInstance() {

                        if (instance == null)

                                    instance= new Singleton2();

                        return instance;

            }         

}

 

(4)

/* 线程安全 并且效率高  能有多个线程访问*/

public class Singleton3 {

            private static Singleton3 instance;

            private Singleton3() {

            }

            public static Singleton3 getIstance() {

                        if (instance == null) {

                                    synchronized (Singleton3.class) {

                                                if (instance == null) {

                                                            instance= new Singleton3();

                                                }

                                    }

                        }

                        return instance;

            }

}

 

三、   程序阅读题(18分)

1.  下面程序片段的输出结果是(4分)

    public static void main(String[]args) {

            int x = 3;

            int y = 1;

            if (x = y)System.out.println("Not equal");

            elseSystem.out.println("Equal");

}

报错

解析:==表示的是数学中的等号,相当于equal;而=表示的是赋值

 

 

2.  在{1}处添加什么代码,可以确保程序输出值是100(6分)

class B implements Runnable{

   int i;

   public void run() {

         try {Thread.sleep(1000);} catch (InterruptedException e) {}

         i = 100;

   }

}

public class Test {

   public static void main(String[] args) throws Exception{

         B b = new B();

         Thread t = new Thread (b);

         t.start();

         // {1}

         int j= b.i;

         System.out.println(j);

   }

}

A. a.wait();

B. t.wait();    报错

C. t.join();

D. t.yield();   0

E. t.notify();  报错

F. a.notify();

G. t.interrupt();  0

(C)

解析:合并线程

3.  请指出下列程序片段的输出结果(8分)

public static voidmain(String[] args) throws Exception {

         String str = "中国";

         System.out.println(str.getBytes("UTF-8").length);

         System.out.println(str.getBytes("GBK").length);

         System.out.println(str.getBytes("ISO-8859-1").length);

         System.out.println(newString(str.getBytes("ISO-8859-1"), "ISO-8859-1"));

         System.out.println(newString(str.getBytes("UTF-8"), "UTF-8"));

         System.out.println(new String(str.getBytes("GBK"),"GBK"));

}

解析:结果如下

6

4

2

??

中国

中国

     

Unicode、UTF-8 和 ISO8859-1区别
在下面的描述中,将以"中文"两个字为例,经查表可以知道其GB2312编码是"d6d0 cec4",Unicode编码为"4e2d 6587",UTF编码就是"e4b8ade69687"。注意,这两个字没有iso8859-1编码,但可以用iso8859-1编码来"表示"。
2. 编码基本知识
最早的编码是iso8859-1,和ascii编码相似。但为了方便表示各种各样的语言,逐渐出现了很多标准编码,重要的有如下几个。
2.1. iso8859-1

属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列。比如,字母a的编码为0x61=97。很明显,iso8859-1编码表示的字符范围很窄,无法表示中文字符。但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用iso8859-1编码来表示。而且在很多协议上,默认使用该编码。比如,虽然"中文"两个字不存在iso8859-1编码,以gb2312编码为例,应该是"d6d0 cec4"两个字符,使用iso8859-1编码的时候则将它拆开为4个字节来表示:"d6 d0 ce c4"(事实上,在进行存储的时候,也是以字节为单位处理的)。而如果是UTF编码,则是6个字节"e4 b8 ad e6 96 87"。很明显,这种表示方法还需要以另一种编码为基础。
2.2. GB2312/GBK

这就是汉字的国标码,专门用来表示汉字,是双字节编码,而英文字母和iso8859-1一致(兼容iso8859-1编码)。其中gbk编码能够用来同时表示繁体字和简体字,而gb2312只能表示简体字,gbk是兼容gb2312编码的。

2.3. unicode

这是最统一的编码,可以用来表示所有语言的字符,而且是定长双字节(也有四字节的)编码,包括英文字母在内。所以可以说它是不兼容iso8859-1编码的,也不兼容任何编码。不过,相对于iso8859-1编码来说,uniocode编码只是在前面增加了一个0字节,比如字母a为"00 61"。
需要说明的是,定长编码便于计算机处理(注意GB2312/GBK不是定长编码),而unicode又可以用来表示所有字符,所以在很多软件内部是使用unicode编码来处理的,比如java。

2.4. UTF

考虑到unicode编码不兼容iso8859-1编码,而且容易占用更多的空间:因为对于英文字母,unicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而产生了utf编码,utf编码兼容iso8859-1编码同时也可以用来表示所有语言的字符,不过,utf编码是不定长编码,每一个字符的长度从1-6个字节不等。另外,utf编码自带简单的校验功能。一般来讲,英文字母都是用一个字节表示,而汉字使用三个字节。
注意,虽然说utf是为了使用更少的空间而使用的,但那只是相对于unicode编码来说,如果已经知道是汉字,则使用GB2312/GBK无疑是最节省的。不过另一方面,值得说明的是,虽然utf编码对汉字使用3个字节,但即使对于汉字网页,utf编码也会比unicode编码节省,因为网页中包含了很多的英文字符。

3. java对字符的处理
在java应用软件中,会有多处涉及到字符集编码,有些地方需要进行正确的设置,有些地方需要进行一定程度的处理。

3.1. getBytes(charset)
这是java字符串处理的一个标准函数,其作用是将字符串所表示的字符按照charset编码,并以字节方式表示。注意字符串在java内存中总是按unicode编码存储的。比如"中文",正常情况下(即没有错误的时候)存储为"4e2d 6587",如果charset为"gbk",则被编码为"d6d0 cec4",然后返回字节"d6 d0 ce c4"。如果charset为"utf8"则最后是"e4 b8 ad e6 96 87"。如果是"iso8859-1",则由于无法编码,最后返回 "3f 3f"(两个问号)。

3.2. new String(charset)

这是java字符串处理的另一个标准函数,和上一个函数的作用相反,将字节数组按照charset编码进行组合识别,最后转换为unicode存储。参考上述getBytes的例子,"gbk" 和"utf8"都可以得出正确的结果"4e2d 6587",但iso8859-1最后变成了"003f 003f"(两个问号)。因为utf8可以用来表示/编码所有字符,所以new String( str.getBytes( "utf8" ), "utf8" ) === str,即完全可逆。

3.3. setCharacterEncoding()

该函数用来设置http请求或者相应的编码。
对于request,是指提交内容的编码,指定后可以通过getParameter()则直接获得正确的字符串,如果不指定,则默认使用iso8859-1编码,需要进一步处理。参见下述"表单输入"。值得注意的是在执行setCharacterEncoding()之前,不能执行任何getParameter()。java doc上说明: This method must be called prior to reading request parameters or reading input using getReader()。而且,该指定只对POST方法有效,对GET方法无效。分析原因,应该是在执行第一个getParameter()的时候,java将会按照编码分析所有的提交内容,而后续的getParameter()不再进行分析,所以setCharacterEncoding()无效。而对于GET方法提交表单是,提交的内容在URL中,一开始就已经按照编码分析所有的提交内容,setCharacterEncoding()自然就无效。对于response,则是指定输出内容的编码,同时,该设置会传递给浏览器,告诉浏览器输出内容所采用的编码。

 

 

四、   编程题(12分)

1.请使用二分查找算法查找字符串数组{"a","b","c","d","e","f","g","h"}中"g"元素。(12分)

解析:

//使用递归算法

public static <E extends Comparable<E>> int binarySearch(E[] array, int from, int to, E key) throws Exception {

        if (from < 0 || to < 0) {

            throw new IllegalArgumentException("params from & length must larger than 0 .");

        }

        if (from <= to) {

            int middle = (from >>> 1) + (to>>> 1); // 右移即除2

            E temp = array[middle];

            if (temp.compareTo(key) > 0) {

                to = middle - 1;

            } else if (temp.compareTo(key) < 0) {

                from = middle + 1;

            } else {

                return middle;

            }

        }

        return binarySearch(array,from, to, key);

  }
Socket编程,写一个Socket客户端和一个Socket服务端,客户端向服务端发送一个“Hello,World”消息。(12分)

解析:

public class SendClass {

      public static void main(String[] args) {

           

//          while(true)

//          {

//                try {

//                      //step1:建立发送对象

//                      DatagramSocket sendScocket = newDatagramSocket();

//                      //step2:建立发送包(buf数据byte[],lenght:数据长度,address:地址,port:端口号)

//                            System.out.print("发送信息:");

//                            String strIn = newScanner(System.in).nextLine();                      

//                            byte[] bMsg = strIn.getBytes();

//                            //准备ip地址

//                            StringstrIp = "192.168.0.105";

//                            InetAddress address =InetAddress.getByName(strIp);//String=>InetAddress

//                            //发送hostport8888

//                            DatagramPacket pack = newDatagramPacket(bMsg, bMsg.length,address,8888);

//                      //step3:发送包

//                      sendScocket.send(pack);

//                      //step4:关闭

//                      sendScocket.close();

//                     

//                      if(strIn.equals("bye"))

//                      {

//                            System.out.println("我不再发包了");

//                            break;

//                      }

//                     

//                } catch (SocketException e) {

//                      // TODO Auto-generated catch block

//                      e.printStackTrace();

//                } catch (UnknownHostException e) {

//                      // TODO Auto-generated catch block

//                      e.printStackTrace();

//                } catch (IOException e) {

//                      // TODO Auto-generated catch block

//                      e.printStackTrace();

//                }

//          }

            try{

                 

                  ServerSocket server = new ServerSocket(9999);

                  Socket client = server.accept();

                  InputStream is = client.getInputStream();

                  InputStreamReader isr = new InputStreamReader(is);

                  BufferedReader clientIn = newBufferedReader(isr);

                 

                  OutputStream os = client.getOutputStream();

                  PrintWriter clientOut = new PrintWriter(os);

                 

                  Scanner sc = new Scanner(System.in);

                  clientOut.println(sc.nextLine());

                  clientOut.flush();

                 

                  String str = clientIn.readLine();

     

                 

                  clientIn.close();

                  clientOut.close();

            }catch(IOException e){

                  e.printStackTrace();

            }

      }

}

 

 

 

package com.javahis.ui.bil;

 

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.Socket;

import java.net.SocketException;

import java.net.UnknownHostException;

import java.util.Scanner;

 

public class ReceiveClass {

 

      /**

       * @param args

       */

      public static void main(String[] args) {

           

//    while(true)

//    {

//          try {

//                System.out.println("建立接收对象>>>>>>>>>>>>");

//                //step1:建立接收对象

//                DatagramSocket receiveSocket = newDatagramSocket(8888);

//                //step2:定义接收包(buf=byte[], length)

//                byte[] buf = new byte[1000];             

//                DatagramPacket pack = new DatagramPacket(buf,buf.length);

//                //step3:接收方法

//                System.out.println("收到信息>>>>>>>>>>>>>");

//                receiveSocket.receive(pack);//阻塞

//                //step4:显示接收信息     

//                String str = new String(buf);

//                System.out.println("["+str+"]");

//                //step5:释放资源

//                receiveSocket.close();

//               

//               

//                if(str.indexOf("bye")!=-1)

//                {

//                      System.out.println("我不再接收包了");

//                      break;

//                }

//          } catch (SocketException e) {

//                // TODO Auto-generated catch block

//                e.printStackTrace();

//          } catch (IOException e) {

//                // TODO Auto-generated catch block

//                e.printStackTrace();

//          }

//    }

            try {

                  Socket client = new Socket("192.168.8.105",9999);

                  System.out.println("服务器端连接成功!");

                 

                  BufferedReader clientIn = new BufferedReader(newInputStreamReader(client.getInputStream()));

                  PrintWriter clientOut = new PrintWriter(clientIn.readLine());

                 

                  System.out.println("服务器说:【"+clientIn.readLine()+"");

                 

                Scanner sc = new Scanner(System.in);

                System.out.println("客户端说:");

               clientOut.print(sc.nextLine());

               clientOut.flush();

               

               clientIn.close();

               clientOut.close();

            } catch (UnknownHostException e) {

                  // TODO Auto-generatedcatch block

                  e.printStackTrace();

            } catch (IOException e) {

                  // TODO Auto-generatedcatch block

                  e.printStackTrace();

            }

      }

 

}

1.请使用Java语言实现多线程模式下的生产者与消费者问题。(10分)

/*@author 

* 生产者与消费者模型中,要保证以下几点:
* 1
同一时间内只能有一个生产者生产    生产方法加锁sychronized
* 2
同一时间内只能有一个消费者消费    消费方法加锁sychronized
* 3
生产者生产的同时消费者不能消费    生产方法加锁sychronized
* 4
消费者消费的同时生产者不能生产    消费方法加锁sychronized
* 5
共享空间空时消费者不能继续消费    消费前循环判断是否为空,空的话将该线程wait,释放锁允许其他同步方法执行
* 6
共享空间满时生产者不能继续生产    生产前循环判断是否为满,满的话将该线程wait,释放锁允许其他同步方法执行   
*/  

//
主类 
class  ProducerConsumer 

    public static voidmain(String[] args)  
    { 
       StackBasket s = new StackBasket(); 
       Producer p = new Producer(s); 
       Consumer c = new Consumer(s); 
       Thread tp = new Thread(p); 
       Thread tc = new Thread(c); 
       tp.start(); 
       tc.start(); 
    } 

 
// 
class Mantou 

    private int id; 
     
    Mantou(int id){ 
       this.id = id; 
    } 
 
    public StringtoString(){ 
       return "Mantou :" + id; 
    } 

 
//
共享栈空间 
class StackBasket 

    Mantou sm[] = newMantou[6]; 
    int index = 0; 
     
    /** 
    * show
生产方法.
    * show
该方法为同步方法,持有方法锁;
    * show
首先循环判断满否,满的话使该线程等待,释放同步方法锁,允许消费;
    * show
当不满时首先唤醒正在等待的消费方法,但是也只能让其进入就绪状态,
    * show
等生产结束释放同步方法锁后消费才能持有该锁进行消费
    * @param m
元素
    * @return
没有返回值 
    */  
 
    public synchronized voidpush(Mantou m){ 
       try{ 
           while(index == sm.length){ 
               System.out.println("!!!!!!!!!
生产满了!!!!!!!!!"); 
               this.wait(); 
           } 
           this.notify(); 
       }catch(InterruptedException e){ 
           e.printStackTrace(); 
       }catch(IllegalMonitorStateException e){ 
           e.printStackTrace(); 
       } 
         
       sm[index] = m; 
       index++; 
       System.out.println("
生产了:" + m + " "+ index + "个馒头"); 
    } 
 
    /** 
    * show
消费方法
    * show
该方法为同步方法,持有方法锁
    * show
首先循环判断空否,空的话使该线程等待,释放同步方法锁,允许生产;
    * show
当不空时首先唤醒正在等待的生产方法,但是也只能让其进入就绪状态
    * show
等消费结束释放同步方法锁后生产才能持有该锁进行生产
    * @param b true
表示显示,false表示隐藏 
    * @return
没有返回值 
    */  
    public synchronized Mantoupop(){ 
       try{ 
           while(index == 0){ 
               System.out.println("!!!!!!!!!
消费光了!!!!!!!!!"); 
               this.wait(); 
           } 
           this.notify(); 
       }catch(InterruptedException e){ 
           e.printStackTrace(); 
       }catch(IllegalMonitorStateException e){ 
           e.printStackTrace(); 
       } 
       index--; 
       System.out.println("
消费了:---------" + sm[index] + " "+ index + "个馒头"); 
       return sm[index]; 
    } 

 
class Producer implements Runnable 

    StackBasket ss = newStackBasket(); 
    Producer(StackBasketss){ 
       this.ss = ss; 
    } 
 
    /** 
    * show
生产进程
    */  
    public void run(){ 
       for(int i = 0;i < 20;i++){ 
           Mantou m = new Mantou(i); 
           ss.push(m); 
//         System.out.println("
生产了:" + m + " "+ ss.index + "个馒头"); 
//         
在上面一行进行测试是不妥的,对index的访问应该在原子操作里,因为可能在push之后此输出之前又消费了,会产生输出混乱 
           try{ 
               Thread.sleep((int)(Math.random()*500)); 
           }catch(InterruptedException e){ 
               e.printStackTrace(); 
           } 
       } 
    } 

 
class Consumer implements Runnable 

    StackBasket ss = newStackBasket(); 
    Consumer(StackBasketss){ 
       this.ss = ss; 
    } 
 
    /** 
    * show
消费进程.
    */  
    public void run(){ 
       for(int i = 0;i < 20;i++){ 
           Mantou m = ss.pop(); 
//         System.out.println("
消费了:---------" + m + " "+ ss.index + "个馒头"); 
// 
同上  在上面一行进行测试也是不妥的,对index的访问应该在原子操作里,因为可能在pop之后此输出之前又生产了,会产生输出混乱 
           try{ 
               Thread.sleep((int)(Math.random()*1000)); 
           }catch(InterruptedException e){ 
               e.printStackTrace(); 
           } 
       } 
    } 

数据库设计题((12分)

请使用关系型数据库结构简单设计移动梦网的梦网服务订购管理系统。

功能描述:用户必须注册(梦网)服务才能使用,即:系统需要管理用户资源。用户使用具体的一项梦网服务前,需要单独订购。系统需要提供统计功能,如:按月统计、按用户订购的服务总数统计等。(8分)

请按你的设计给出如下查询功能:

1) 统计每个月的注册用户数量(2分)

2) 统计订购了超过两项梦网服务的用户信息(2分)

用户信息表

Userinfo(user_id,regist_date)

梦网服务表

Service(service_id,order_time)

订单表

user_service(user_id,service_id)

中间表

(1)

 SELECTCOUNT(*)

  FROMuserinfo

 WHEREregist_date BETWEEN TO_DATE('05/08/201314:08:40',

                                    'MM/DD/YYYYHH24:MI:SS'

                                   )

                       ANDTO_DATE('06/08/201314:08:40',

                                    'MM/DD/YYYYHH24:MI:SS'

                                   )

(2)

SELECT A.USER_ID

  FROMUSERINFO A,

       (SELECT   COUNT (*)ASCOUNT,USER_ID

            FROMUSER_SERVICE

        GROUPBYUSER_ID) B

 WHERE A.USER_ID=B.USER_IDANDB.COUNT>=2

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值