做爲本人首篇黑馬技術博客有必要交代一下背景。我的理解博客的用做在於於己在於交流,於他在於學習,在交流學習中共同成長。下面進入正題。本文主要是介紹在作黑馬入門測試時的一些問題(這個應該不是泄露題庫吧)。 java
本文只要是講述黑馬程序員基礎測試題的6-10題,回過頭來分析明顯感受到難度的上升,考察的級別也有所提高,尤爲是第九、第10,並且有必定的實用性,後文會進行分析。 程序員
第六題是關於面向對象的繼承的基本知識,這個題屬於大路邊上的題,沒有難度,這篇博客只給出原題,我會在後續的博客中進行更深刻的分析。題目描述: 算法
聲明類Person,包含2個成員變量:name、age。定義函數sayHello(),調用時輸出:我叫***,今年***歲了。聲明類Chinese繼承Person。 數組
第七題是關於數組去重的,題目描述: 緩存
數組去重複,例如: 原始數組是{4,2,4,6,1,2,4,7,8},獲得結果{4,2,6,1,7,8} 函數
這個題其實沒有什麼難度,可是有一個特色是輸出的結果不是按照排序以後輸出而是隻是將原來的數組中重複的提出,可是順序不變。剛開始個人想法是先借助Arrays.sort(),將數組排序而後先後進行比較,若是後一個和前一個相同則不輸出,不然就輸出,雖然能夠實現去重,可是順序改變了,顯然不知足題目要求,具體程序實現以下: 工具
@Test學習
public void testMain()測試
{spa
int a[]={4,2,4,6,1,2,4,7,8};
Arrays.sort(a);//將數組從小到大進行排序
moveTheSame(a);//調用去重函數
}
private void moveTheSame(int[] a) {
for(int i=0;i<a.length-1;i++)
{
if(a[i]!=a[i+1])
System.out.print(a[i]);
}
if(a[a.length-2]!=a[a.length-1])//處理邊界狀況,
System.out.println(a[a.length-1]);
}
另一種作法是經過Set集合元素不可重複的屬性進行。具體實現以下:
@Test
public void testMain()
{
int a[]={4,2,4,6,1,2,4,7,8};
int b[]=moveTheSame(a);//數組去重
for(int i:b)//遍歷輸出
System.out.print(i);
}
private int[] moveTheSame(int[] a)
{
Set<Integer> mySet=new HashSet<Integer>();
for(int i=0;i<a.length;i++)//將元素放入Set集合
{
mySet.add(a[i]);
}
Object[] o=mySet.toArray();
int b[]=new int[o.length];
for(int i=0;i<b.length;i++)//爲了保證與原數組類型一致,若是隻是輸出的話直接返回Object就行
b[i]=Integer.parseInt(o[i].toString());
return b;//返回原數組類型
}
還有一種作法是將數組轉化爲String,而後依次進行比較(和第一個類似),可是考慮到大於10的數,因此放棄,可是思想有借鑑價值,下面的結果就是借鑑這個原理獲得的
public static void main(String[] args) {
int a[] = { 4, 2, 4, 6, 1, 2, 4, 7, 8 };
int b[] = moveTheSame(a);// 調用數組去重方法
for (int i = 0; i < b.length; i++)
// 按原格式輸出
if (i != b.length - 1)
System.out.print(b[i] + ",");
else
System.out.print(b[i]);
}
private static int[] moveTheSame(int[] a) {
List<Integer> list = new ArrayList<Integer>();// 聲明一個ArrayList,默認值爲null
for (int i = 0; i < a.length; i++)
// 依次編譯數組,若是list中不包含當前的元素則將當前元素加入到list,若是包含則忽略。
if (!list.toString().contains(a[i] + ""))
list.add(a[i]);
int b[] = new int[list.size()];
Object o[] = list.toArray();// 將list中元素轉化爲數組
for (int i = 0; i < b.length; i++)
// 一樣是爲了保證與原數組類型一直
b[i] = Integer.parseInt(o[i].toString());
return b;
}
上面介紹了三種方法,可是輸出結果都是已排序和題目要求矛盾,上面介紹第三中方法,這種方法思想借助上面的分析,其實也是經過上面的分析得出的最終解決方案。咱們在作一些算法題目每每不是一步就成功,而是將大問題分解爲小問題一步步去實現。
總結:
1,觀察數組特色得知數組的輸出結果是一個無序數組,因此使用將數組轉化爲set集合的方案
(或者先借助Arrays.sort()進行排序,而後進行判斷)行不通。
2,考慮將數組轉化爲Stirng類型,藉助中間變量去判斷中間變量中是否包含當前迭代元素,
若是包含則忽略,不包含則將當前元素加入到中間變量,考慮到大於10的數據,放棄本方案
3,直接藉助List,若是中間變量List中存在當前變量則忽略,不存在則加入list中,
能夠解決上面出現的問題。可是注意返回的類型應該保持與原來數組類型一致,
所以迭代將每一個Integer元素轉化爲int,而後返回int數組
你們能夠看到簡簡單單一道題有着這麼大的工做量,當你寫的多了對程序的設計就很快作出了,一步一步來纔是王道。
第八題也是考察的只是是內部類已經其調用,這也是一個很重要的一個知識點,因爲考察的形式簡單,在此也就簡單的分析。題目描述以下:
在打印語句中如何打印這3個x變量?
class A // 外部類
{
int x = 1;
class B// 內部類
{
int x = 2;// 內部類屬性
void func() //內部類成員方法
{
int x = 3;
System.out.println(x);
}
}
}
參考解決方案:
A a=new A();//創建外部類的實例對象
System.out.println(a.x);//經過外部類的實例對象調用外部類的屬性
A.B b=a.new B();//實例化內部類的對象
System.out.println(b.x);//經過內部類的實例對象調用內部類的屬性
b.func();//經過內部類的對象調用內部類的成員方法
第九題也是我對我啓發特別大的一個題目,是關於IO流的,以前學習過可是不是很熟悉,個人瞭解IO無非就是文件讀寫,也就是上傳下載。在作JavaWeb項目時一般會用到工具包,因此對IO的重要性就淡化了好多,可是這道題給了我不少啓發。題目描述以下:
編寫程序,將指定目錄下全部.java文件拷貝到另外一個目的中,並將擴展名改成.txt
思路:
1.遍歷指定目錄的文件夾,並將以.java結尾的文件封裝到list中,以便後續操做。
2.建立一個目的目錄myDir
3.遍歷list,指定文件目錄爲myDir,文件名爲源文件名,後綴爲.txt
程序實現以下:
public static void main(String[] args) throws IOException {
File dir = new File("F:\\a");
List<File> list = new ArrayList<File>();
file2List(dir, list);
list2TextbyChar(list);
}
// 遍歷指定目錄下的全部文件,並將*.java文件封裝到List中
static void file2List(File dir, List<File> list) {
File files[] = dir.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {// 若是當前文件爲目錄,遞歸遍歷
file2List(files[i], list);
} else if (files[i].toString().endsWith(".java"))// 若是當前文件是以.java結尾,也就是java文件那麼將該文件添加到list中
list.add(files[i]);
}
}
// 遍歷封裝了java文件的list,並將對應信息寫到指定目錄下對應的*.txt文件中
static void list2TextbyChar(List<File> list) throws IOException {
File f = new File("E:\\myDir");// 指定目標文件目錄,若是不存在就新建該目錄
f.mkdirs();
for (int i = 0; i < list.size(); i++) {
// 獲取目標文件路徑,已經源文件的文件名,將.java替換爲.txt
String fileName = f+ "\\"+
list.get(i).getName().toString().substring(0,list.get(i).getName().toString().length() - 5)+ ".txt";
FileReader fr = new FileReader(list.get(i).getAbsoluteFile());// 讀取每一個文本文件的信息
FileWriter fw = new FileWriter(fileName);// 建立同名目錄
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fw.close();
fr.close();
}
}
說這個題對個人啓發大是由於有一個問題一直困擾着我,就是本人保存文件都是按照月份進行的可是時間長了去找文件就會很麻煩有時很長時間都找不到,非常糾結,在這個題目的啓發下我將磁盤上全部文件,按照後綴名進行分類。這樣對我來講帶來了很大便利,好比我要找JDK的API,那麼我只需去chm文件夾下找就ok了。下面程序演示個人實現:
public static void main(String[] args) throws IOException {
File dir=new File("E:\\");
List<File> list = new ArrayList<File>();
file2List(dir, list);
list2TextbyByte(list);
}
// 遍歷指定目錄下的全部文件,並將*.java文件封裝到List中
static void file2List(File dir, List<File> list) {
File files[] = dir.listFiles();
int b = 0;
try {
for (int i = 0; i < files.length; i++) {
/*
if (!files[i].getAbsolutePath().contains("$")
&& !files[i].getAbsolutePath().contains("System")
&& !files[i].getAbsolutePath().contains("RECYCLER")
&& !files[i].getAbsolutePath().contains("Documents and Settings")
&&!files[i].getAbsolutePath().contains("Program"))*/
if (!files[i].isHidden())//這個是爲了防止讀取系統關鍵文件(會禁止訪問而形成異常)
{
b = i;
if ( files[i].isDirectory()) {
file2List(files[i], list);
}
if (files[i].getAbsolutePath().endsWith(".chm"))
list.add(files[i]);
}
else
continue;
}
} catch (Exception e) {
System.out.println(files[b].getAbsolutePath());
e.printStackTrace();
}
}
static void list2TextbyByte(List<File> list) throws IOException {
File f = new File("C:\\mychm");// 知道目標文件目錄,若是不存在就新建該目錄
f.mkdirs();
for (int i = 0; i < list.size(); i++) {
// 獲取目標文件路徑,已經源文件的文件名
String fileName = f + "\\" + list.get(i).getName().toString();
FileInputStream fis = new FileInputStream(list.get(i)
.getAbsoluteFile());
FileOutputStream fos = new FileOutputStream(fileName);
int ch = 0;
byte by[] = new byte[1024 * 1024];
while ((ch = fis.read(by)) != -1) {
fos.write(by, 0, ch);
}
fos.close();
fis.close();
}
}
第十題是關於字節流的,在一份試卷中有兩個題並且是壓軸題是用到了IO,因而可知IO的重要性,題目描述以下:
編寫函數,從一個字符串中按字節數截取一部分,但不能截取出半個中文(GBK碼錶)
例如:從"HM程序員"中截取2個字節是"HM",截取4個則是"HM程",截取3個字節也要是"HM"而不要出現半個中文
分析:在GBK下,一個英文字符爲一個字節,一個漢字爲兩個字節。
處理時能夠分狀況進行處理:
1.讀取字節時按照GBK的方式讀取
2.用變量count控制讀取的次數,當達到截取長度時break,結束程序
3.定義一個長度爲1個字節的byte數組by[],用於處理單字節的內容,同時負責臨時緩存半個中文的字符
4.定義一個長度爲2個字節的byte數組by2[],敢於處理中文。
程序實現以下:
public static void main(String[] args) throws IOException {
mychar();
}
static void mychar() throws IOException {
String s = "HM程序員";// 初始化字符串
// 將字符串按字節(GBk)放在InputStream中
InputStream is = new ByteArrayInputStream(s.getBytes("GBK"));
// 定義須要截取字節的長度,以及給計數標記賦初值0,用以控制跳出條件
int n = 0, count = 0;
Scanner sc = new Scanner(System.in);
System.out.print("請輸入截取字節長度:");
// 接收要截取的字節長度
n = sc.nextInt();
int len = 0;
// 用於處理長度爲1的字符
byte[] by = new byte[1];
// 用於處理長度爲2的字符
byte[] by2 = new byte[2];
int i = 0;
while ((len = is.read(by)) != -1)
{
if (!(by[0] < 0))// 字符
{
System.out.print((char) by[0]);// 將一個字節強轉爲字符並輸出
} else if (i < 1)// 處理半個中文
{
i++;
by2[0] = by[0];
} else // 當i>0時表示處理漢子的低位字節,兩個字節爲一個漢字
{
by2[1] = by[0];
System.out.print(new String(by2));// 將分開的兩個字節合成爲一箇中文字符並輸出
by2 = new byte[2];
i = 0;
}
count++;
if (count == n)
break;
}
}
到此,試卷的講解結束,謝謝您的閱讀。