java筆試

1,簡單描述數組(vector)與鏈表(list)的區別以及應用場景。
(java)java中vetcor和ArrayList的區別
首先看這兩類都實現List接口,而List接口一共有三個實現類,分別是ArrayList、Vector和LinkedList。List用於存放多個元素,能夠維護元素的次序,並且允許元素的重複。
3個具體實現類的相關區別如下:

1.ArrayList是最常用的List實現類,內部是通過數組實現的,它允許對元素進行快速隨機訪問。數組的缺點是每個元素之間不能有間隔,當數組大小不滿足時需要增加存儲能力,就要講已經有數組的數據複製到新的存儲空間中。當從ArrayList的中間位置插入或者刪除元素時,需要對數組進行復制、移動、代價比較高。因此,它適合隨機查找和遍歷,不適合插入和刪除。

2.Vector與ArrayList一樣,也是通過數組實現的,不同的是它支持線程的同步,即某一時刻只有一個線程能夠寫Vector,避免多線程同時寫而引起的不一致性,但實現同步需要很高的花費,因此,訪問它比訪問ArrayList慢。

3.LinkedList是用鏈表結構存儲數據的,很適合數據的動態插入和刪除,隨機訪問和遍歷速度比較慢。另外,他還提供了List接口中沒有定義的方法,專門用於操作表頭和表尾元素,可以當作堆棧、隊列和雙向隊列使用。

查看Java源代碼,發現當數組的大小不夠的時候,需要重新建立數組,然後將元素拷貝到新的數組內,ArrayList和Vector的擴展數組的大小不同。

ArrayList中:

public boolean add(E e) {
     ensureCapacity(size + 1);  // 增加元素,判斷是否能夠容納。不能的話就要新建數組
     elementData[size++] = e;
     return true;
 }
  public void ensureCapacity(int minCapacity) {
     modCount++; 
     int oldCapacity = elementData.length;
     if (minCapacity > oldCapacity) {
         Object oldData[] = elementData; // 此行沒看出來用處,不知道開發者出於什麼考慮
         int newCapacity = (oldCapacity * 3)/2 + 1; // 增加新的數組的大小
         if (newCapacity < minCapacity)
        newCapacity = minCapacity;
             // minCapacity is usually close to size, so this is a win:
             elementData = Arrays.copyOf(elementData, newCapacity);
     }
 }

Vector中:

private void ensureCapacityHelper(int minCapacity) {
     int oldCapacity = elementData.length;
     if (minCapacity > oldCapacity) {
         Object[] oldData = elementData;
         int newCapacity = (capacityIncrement > 0) ?
        (oldCapacity + capacityIncrement) : (oldCapacity * 2);
         if (newCapacity < minCapacity) {
        newCapacity = minCapacity;
         }
        elementData = Arrays.copyOf(elementData, newCapacity);
     }
 }

關於ArrayList和Vector區別如下:
1.ArrayList在內存不夠時默認是擴展50% + 1個,Vector是默認擴展1倍。
2.Vector提供indexOf(obj, start)接口,ArrayList沒有。
3.Vector屬於線程安全級別的,但是大多數情況下不使用Vector,因爲線程安全需要更大的系統開銷。
(c++):(由於筆試時沒有看過C++,所以不知道考的是c++的內容,這裏先寫一點,後續加上)http://blog.csdn.net/alex_xhl/article/details/37692297
List封裝了鏈表,Vector封裝了數組, list和vector得最主要的區別在於vector使用連續內存存儲的,他支持[]運算符,而list是以鏈表形式實現的,不支持[]。

Vector對於隨機訪問的速度很快,但是對於插入尤其是在頭部插入元素速度很慢,在尾部插入速度很快。List對於隨機訪問速度慢得多,因爲可能要遍歷整個鏈表才能做到,但是對於插入就快的多了,不需要拷貝和移動數據,只需要改變指針的指向就可以了。另外對於新添加的元素,Vector有一套算法,而List可以任意加入。
2,C中的malloc和C++中的new有什麼區別?
1,malloc與free是C++/C語言的標準函數,new/delete是C++的運算符。它們都可以用於申請動態內存和釋放內存。
2,對於非內部數據類型的對象而言,光用malloc/free無法滿足動態對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自定執行析構函數。由於malloc/free是庫函數而不是運算符,不在編譯器控制權限內,不能夠把執行構造函數和析構函數的任務強加於malloc/free。
3,因此C++語言需要一個能完成動態內存分配和初始化工作的運算符new,以一個能完成清理與釋放內存工作運算符delete。注意new/delete不是庫函數。
4,C++程序經常要調用C函數,而C程序只能用malloc/free管理動態內存
new是操作符,malloc是分配內存的函數,供你調用
new是保留字,不需要頭文件支持。malloc需要頭文件庫函數支持。
new建立的是一個對象。malloc分配的是一塊內存。
new建立的對象你可以把它當成一個普通的對象,用成員函數訪問,不要直接訪問它的地址空間。malloc分配的是一塊內存區域,就用指針訪問好了,而且還可以在裏面移動指針。
  簡而言之:
  new 是一個操作符,可以重載
  malloc是一個函數,可以覆蓋
  new 初始化對象,調用對象的構造函數,對應的delete調用相應的析構函數
  malloc僅僅分配內存,free僅僅回收內存
malloc函數
原型:extern void*malloc(unsigned int num_bytes);
用法:#include<malloc.h>
功能:分配長度爲num_bytes字節的內存塊
說明:如果分配成功則返回指向被分配內存的指針,否則返回空指針NULL。當內存不再使用時,應使用free()函數將內存塊釋放。
舉例:

//malloc.c
#include<syslib.h>
#include<malloc.h>
main(){
    char *p;
    clrscr();//清空顯示
    p=(char*)malloc(100);
    if(p)
    printf("Memory Allocated at:%x",p);
    else
    printf("Not Enough Memory!\n");
    free(p);
    getchar();
    return 0;
}

函數聲明(函數原型):
void *malloc(int size);
說明:malloc向系統申請分配指定size個字節的內存空間。返回類型是void*類型。
void*表示未確定類型的指針。C,C++規定,void* 類型可以強制轉換爲任何其它類型的指針。從函數聲明上可以看出。malloc 和 new 至少有兩個不同: new 返回指定類型的指針,並且可以自動計算所需要大小。比如:
int *p;
p = new int; //返回類型爲int* 類型(整數型指針),分配大小爲 sizeof(int);
或:
int* parr;
parr = new int [100]; //返回類型爲 int* 類型(整數型指針),分配大小爲 sizeof(int) * 100;
而 malloc 則必須由我們計算要字節數,並且在返回後強行轉換爲實際類型的指針。
int* p;
p = (int *) malloc (sizeof(int));
第一、malloc 函數返回的是 void * 類型,如果你寫成:p = malloc (sizeof(int)); 則程序無法通過編譯,報錯:“不能將 void* 賦值給 int * 類型變量”。所以必須通過 (int *) 來將強制轉換。
第二、函數的實參爲 sizeof(int) ,用於指明一個整型數據需要的大小。如果你寫成:
int* p = (int *) malloc (1);
代碼也能通過編譯,但事實上只分配了1個字節大小的內存空間,當你往裏頭存入一個整數,就會有3個字節無家可歸,而直接“住進鄰居家”!造成的結果是後面的內存中原有數據內容全部被清空。
malloc 也可以達到 new [] 的效果,申請出一段連續的內存,方法無非是指定你所需要內存大小。
比如想分配100個int類型的空間:
int* p = (int ) malloc ( sizeof(int) 100 ); //分配可以放得下100個整數的內存空間。 另外有一點不能直接看出的區別是,malloc 只管分配內存,並不能對所得的內存進行初始化,所以得到的一片新內存中,其值將是隨機的。 除了分配及最後釋放的方法不一樣以外,通過malloc或new得到指針,在其它操作上保持一致。

3,二進制數組11101101轉換爲十八(18)進制數是多少?

4,操作系統的主要功能有哪些?列出你所知道的操作系統?

5,請寫出下面代碼在32位和64位操作系統下的輸出結果?

void_test(){
    char x[] = "csdn123";
    cahr y[20] = "csdn123";
    wchar_t wch[] = L"csdn123";

    printf("%d,%d,%d,%d,%d,%d,%d,%d",
        sizeof(char),sizeof(char*),
        sizeof(x),strlen(x),
        sizeof(y),strlen(y),
        sizeof(wch),wcslen(wch)
        );          
}

6,請寫出下面有什麼錯誤(如果有的話),如何修改?

void swap(int *p1, int *p2){
    int *p;
    *p = *p1;
    *p1 = *p2;
    *p2 = *p;
}
void swap(int *p1, int *p2) 
{ 
    int *p;
    *p=*p1; //這句話有錯,因爲int *p是一個指針,並且在定義之後未初始化,所以其指向的地址也是不
    //確定的。直接讓*p=*p1會讓一個隨機地址裏的內容等於*p1的內容,所以可能導致系統崩潰。編譯
    //也不會通過。
    *p1=*p2; 
    *p2=*p; 
}

可如此更改

void swap(int *p1, int *p2) 
{
    int tmp=0; 
    int *p=&tmp; 
    *p=*p1; 
    *p1=*p2; *p2=*p; 
}申請一個臨時變量讓P去指向就不會出錯了。

或者更簡單

void swap(int *p1, int *p2) 
{
    int tmp=0; 
    tmp=*p1; 
    *p1=*p2;
     *p2=tmp; 
}

7,請寫出下面的輸出結果

void main(void){
    int a[5] = {1,2,3,4,5};
    int *ptr = (int*)(&a+1);
    printf("%d,%d",*(a+1),*(ptr-1));
}

8,實現函數:輸入年月日時分秒(字符串),輸出該年月日時分秒後的n秒對應的時間(字符串),比如2014-12-31 23:59:56 ,n=10,則輸出2015-01-01 00:00:06,(不允許使用系統函數),輸入輸出的時間格式:YYYY-MM-DD hh:mm:ss

package com.xhd.ths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Timetran {
    public static void main(String args[]) throws ParseException{
        String time = "2014-12-31 23:59:56";//輸入時間
        int sends = 10;//輸入秒數
        String newtime = printTime(a,b);//新輸出時間
        System.out.println(newtime);
    }
    public static String printTime(String time,int sends) throws ParseException{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date =sdf.parse(time);
        //獲取時間戳
        long longTime =date.getTime();
        //時間戳裏的單位是毫秒
        longTime+=sends*1000;
        Date date1 = new Date(longTime);
        return sdf.format(date1);
    }

}

9,實現函數:十進制轉二進制 char*dec_to_bin(int_input,char*_output,int_len);
例如:輸入0x7FF00FEF 輸出:11111111111000000001111111101111

A,請估算一下在大學期間你總共寫過多少行代碼?你認爲最得意的代碼是什麼?請簡單描述一下。
B,在多CPU,多核時代,如何在軟件開發層面提升軟件的性能?在實現個過程是會遇到哪些問題?
C,如果你可以爲自己熟悉的語言增加新的特性,你最想加的特性是哪些?

1,(JAVA)實現一個線程類有幾種方式?有幾種啓動方式?請編碼實現,並啓動。
這篇博客介紹的比較詳細:http://blog.csdn.net/aboy123/article/details/38307539
java5以前有兩種方式:分別是使用new Thread()和new Thread(runnable)形式,第一種直接調用thread的run方法。第二種調用runnable的run方法。
第一種:
new Thread(){}.start();表示調用Thread子類對象的run方法,new Thread的匿名子類的實例對象,子類加上run方法後的代碼如下:

new Thread(){
   public void run(){
   }
}.start()
class MyThread extends Thread(){
    public void run(){
    //do
    }
};
//創建並啓動線程
MyThread mythread = new MyThread();
mythread.start();

第二種:
new Thread(new Runnable(){}).start();這表示調用Thread對象接受的Runnable對象的run方法,new Runnable(){}表示一個Runnable的匿名子類的實例對象,runnable的子類加上run方法後的代碼如下:

new Thread(new Runnable(){
               public void run(){
               }    
        }
   ).start();
class MyThread implements Runnable{
        public void run(){
        //do
    }
}
//創建並啓動一個線程
MyThread mythread = new MyThread();
new Thread(mythread).start();

第三種:實現Callable接口,重寫call函數
Callable是類似於Runnable的接口,實現Callable接口的類和實現Runnable的類都是可被其它線程執行的任務。
Callable和Runnable有幾點不同:
①Callable規定的方法是call(),而Runnable規定的方法是run().
②Callable的任務執行後可返回值,而Runnable的任務是不能返回值的
③call()方法可拋出異常,而run()方法是不能拋出異常的。
④運行Callable任務可拿到一個Future對象,Future表示異步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,並檢索計算的結果.通過Future對象可瞭解任務執行情況,可取消任務的執行,還可獲取任務執行的結果。

2,(JAVA)畫出JAVA中集合類的繼承關係圖。
這裏寫圖片描述

3,(JAVA)實現函數:輸出九九乘法表。

package com.xhd.ths;

public class Nine {
    public static void main(String[] args){
        System.out.println();
        int i;
        int j;
        for(i=1;i<=9;i++){
            for(j=1;j<=i;j++){
                System.out.println(j+"*"+i+"="+i*j+"\t");               
            }
            System.out.println();
        }
    }

}

4,(C/C++)實現一個適用於多線程的單列模式的類。
5,(C/C++)windows平臺的動態鏈接庫(DLL)有哪幾種調用方式?比較一下優缺點。
6,(C/C++)實現函數:輸入一個文本文件的文件名(文件大小在100M-6G之間)和一個關鍵字字符串,要求在文件中搜索並統計關鍵字的搜索次數。
7,(搜索)請寫出k-means算法的僞代碼
8,(搜索)我們有1000個公司名稱,如何從互聯網上獲得更多的公司名稱?
9,(搜索)請描述你所知道的分類算法,並列出影響分類結果的各種因素。
10,(PHP)用最簡短的代碼編寫一個獲取3個數字中最大值的函數。
11,(PHP)請描述==和===的區別,並列出什麼情況下一定要===,什麼情況下用==更合適(需要自己創建一個應用場景,來說明它們在實際應用中的用途)
12,(PHP)請簡述php中傳值和傳引用的區別,什麼時候傳值什麼時候傳引用?如何傳引用?
13,(PHP)在php程序開發中使用echo,print()和print_r()打印有什麼區別?

面試題:1樹的概念,有兩個變量,如何在不使用第三個變量的情況下相互換兩個變量的值。
2,面向對象的三大特性,多態具體是什麼。
3,重載和重寫的區別
4,使用過JAVA哪些開源框架
5,數據庫中inner join和left join的區別
6,九九乘法表

發佈了52 篇原創文章 · 獲贊 9 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章