Android面試題3
答: Android中介面部分也採用了當前比較流行的MVC框架。
在Android中:
1) 檢視層(View):一般採用XML檔案進行介面的描述,使用的時候可以非常方
便的引入。也可以使用JavaScript+HTML等的方式作為View層,通過WebView組
件載入,同時可以實現Java和JavaScript之間的通訊。
2) 控制層(Controller):這句話也就暗含了不要在Acitivity中寫程式碼,要通過Activity
交割Model業務邏輯層處理,這樣做的另外一個原因是Android中的Acitivity的響
應時間是5s,如果耗時的操作放在這裡,Android的控制層的重任通常落在了眾多
的Acitvity的肩上,程式就很容易被回收掉。
- 模型層(Model):對資料庫的操作、對網路等的操作都應該在Model裡面處理,
當然對業務計算等操作也是必須放在的該層的。
在Android SDK中的資料繫結,也都是採用了與MVC框架類似的方法來顯示資料。在控制層上將資料按照檢視模型的要求(也就是Android SDK中的Adapter)封裝就可以直接在檢視模型上顯示了,從而實現了資料繫結。比如顯示Cursor中所有資料的ListActivity,其檢視層就是一個ListView,將資料封裝為ListAdapter,並傳遞給ListView,資料就在ListView中顯示。
即畫素,1px代表螢幕上一個物理的畫素點;
px單位不被建議使用,因為同樣100px的圖片,在不同手機上顯示的實際大小可能不同
dp = dip : device independent pixels(裝置獨立畫素). 不同裝置有不同的顯示效果,這個和裝置硬體有關,一般我們為了支援WVGA、HVGA和QVGA 推薦使用這個,不依賴畫素。
與縮放無關的抽象畫素(Scale-independent Pixel)。sp和dp很類似但唯一的區別是,Android系統允許使用者自定義文字尺寸大小(小、正常、大、超大等等),當文字尺寸是“正常”時1sp=1dp=0.00625英寸,而當文字尺寸是“大”或“超大”時,1sp>1dp=0.00625英寸。類似我們在windows裡調整字型尺寸以後的效果——視窗大小不變,只有文字大小改變。
答:1)應用程式層 java語言 應用程式開發
- 應用程式框架層 java語言 OS定製 framework層開發
- 系統執行庫層 C C++ 實現 so庫
- Linux核心層
答:最常用的佈局有以下這幾種:
第一種:幀佈局(框架佈局)FrameLayout,在這個佈局中,所有的子元素統統放於這塊區域的左上角,並且後面的子元素直接覆蓋在前面的子元素之上,將前面的子元素部分和全部遮擋。
第二種:線性佈局LinearLayout,最常用的一種佈局方式,所有子控制元件的對齊方式,取決於如何定義 orientation的屬性:vertical 垂直方向 ,如果按照這種方向所有的子控制元件將按照垂直的方式分佈在佈局上,每行只允許有一個子元素,horizontal水平方向 ,這時子控制元件將會以水平的方向分佈在佈局中。
第三種:絕對佈局AbsoluteLayout,又可以叫做座標佈局,可以直接指定子元素的絕對位置,這種佈局簡單直接,直觀性強,但是由於手機螢幕尺寸差別比較大,使用絕對定位的適應性會比較差。
第四種:相對佈局RelativeLayout,允許子元素指定它們相對於其父元素或兄弟元素的位置,這是實際佈局中最常用的佈局方式之一。它靈活性大很多,當然屬性也多,操作難度也大,屬性之間產生衝突的的可能性也大,使用相對佈局時要多做些測試。
第五種:表格佈局TableLayout,表格佈局TableLayout以行列的形式管理子元素,每一行是一個TableRow佈局物件,當然也可以是普通的View物件,TableRow裡每放一個元素就是一列,總列數由列數最多的那一行決定。
第六種:網格佈局 GridLayout,在Android 4.0中,新引入的GridLayout網格佈局,GridLayout佈局使用虛細線將佈局劃分為行,列和單元格,也支援一個控制元件在行,列上都有交錯排列。而GridLayout使用的其實是跟LinearLayout類似的API,只不過是修改了一下相關的標籤而已,所以對於開發者來說,掌握GridLayout還是很容易的事情。
(Android 4.0的SDK已經發布,在眾多的新增特性中,其中對開發者來說比較重要的特性之一,是新增的兩種介面佈局方式:Space和Gridlayout)
答:單例模式;工廠模式;
觀察者模式:ContentObserver, 監聽ContentProvider ContentResolver;
介面卡模式Adapter(SimpleAdapter BaseAdapter ArrayAdapter CursorAdapter)以及各種Adapter的資料來源;
代理模式 AOP;
答: 氣泡排序 O(n^2) : 氣泡排序也是最簡單最基本的排序方法之一。氣泡排序的思想很簡單,就是以此比較相鄰的元素大小,將小的前移,大的後移,就像水中的氣泡一樣,最小的元 素經過幾次移動,會最終浮到水面上。
快速排序O(n log n) : 快速排序採用的思想是分治思想。快速排序演算法的核心演算法是分割槽操作,即如何調整基準的位置以及調整返回基準的最終位置以便分治遞迴。
插入排序 O(n^2) :將新來的元素按順序放入一個已有的有序序列當中。
選擇排序 O(n^2) :第i趟簡單選擇排序是指通過n-i次關鍵字的比較,從n-i+1個記錄中選出關鍵字最小的記錄,並和第i個記錄進行交換。共需進行i-1趟比較,直到所有記錄排序完成為止。
for (int i = 0; i < num.length; i++) {
// 內迴圈控制比較後移位
for (int j = num.length-1; j > i ; j--) {
if (num[j-1]>num[j]) {
temp = num[j-1];
num[j-1] = num[j];
num[j] = temp;
}
}
快速排序(Quicksort)是對氣泡排序的一種改進。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。
public class QuickSort {
public static void main(String[] args) {
Integer[] list={34,3,53,2,23,7,14,10};
QuickSort qs= new QuickSort();
qs.quick(list);
for( int i=0;i<list. length;i++){
System. out.print(list[i]+ " ");
}
System. out.println();
}
public void quick(Integer[] str) {
if (str.length > 0) { //檢視陣列是否為空
_quickSort(str, 0, str. length - 1); //從第一個數到最後一個數
}
}
public void _quickSort(Integer[] list, int low, int high) { //low,最小索引,high最高索引
if (low < high) {
int middle = getMiddle(list, low, high); //將list陣列進行一分為二 ,取得中間值對應的索引
_quickSort(list, low, middle - 1); //對低字表進行遞迴排序
_quickSort(list, middle + 1, high); //對高字表進行遞迴排序
}
}
//獲得陣列的中間值的索引(即位置)(引數:陣列,最低索引,最高索引)
public int getMiddle(Integer[] list, int low, int high) {
int tmp = list[low]; //先用陣列的第一個值作為中軸(對比值)
while (low < high) {
//後一半的陣列,把中值與最後一個比,如果不比它大則不交換則再與前一個再比
while (low < high && list[high] > tmp) {
high--;
}
list[low] = list[high]; //最後list[high]小於對比值時,則把這個值移到低端------------>這裡list[low]值發生了改變 ,為下面迴圈作準備
while (low < high && list[low] < tmp) { //前一半,中值與低端值比,如果比中值小則與下一個數比
low++; //修改索引為下一個數
}
list[high] = list[low]; //否則,如果list[low]比中軸大,則把這個值移到高階------------->這裡list[high]值發生了改變
}
list[low] = tmp; //上面迴圈處理完後,把當前中軸值存到當前陣列的低端(其實當前的low在上面處理完後,已逐漸修改為中間的索引)
System.out.println(low +"============"+tmp);
return low; //返回中軸的位置
}
}
答:Java語言的關鍵字,當它用來修飾一個方法或者一個程式碼塊的時候,能夠保證在同一時刻最多隻有一個執行緒執行該段程式碼。
一、當兩個併發執行緒訪問同一個物件object中的這個synchronized(this)同步程式碼塊時,一個時間內只能有一個執行緒得到執行。另一個執行緒必須等待當前執行緒執行完這個程式碼塊以後才能執行該程式碼塊。
二、然而,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,另一個執行緒仍然可以訪問該object中的非synchronized(this)同步程式碼塊。
三、尤其關鍵的是,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,其他執行緒對object中所有其它synchronized(this)同步程式碼塊的訪問將被阻塞。
四、第三個例子同樣適用其它同步程式碼塊。也就是說,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,它就獲得了這個object的物件鎖。結果,其它執行緒對該object物件所有同步程式碼部分的訪問都被暫時阻塞。
五、以上規則對其它物件鎖同樣適用.
答:1)、新建狀態(New):新建立了一個執行緒物件。
2)、就緒狀態(Runnable):執行緒物件建立後,其他執行緒呼叫了該物件的start()方法。該 狀態的執行緒位於可執行執行緒池中,變得可執行,等待獲取CPU的使用權。
3)、執行狀態(Running):就緒狀態的執行緒獲取了CPU,執行run()方法。
4)、阻塞狀態(Blocked):阻塞狀態是執行緒因為某種原因放棄CPU使用權,暫時停止運 行。直到執行緒進入就緒狀態,才有機會轉到執行狀態。阻塞的情況分三種:
(一)、等待阻塞:執行的執行緒執行wait()方法,JVM會把該執行緒放入等待池中。
(二)、同步阻塞:執行的執行緒在獲取物件的同步鎖時,若該同步鎖被別的執行緒佔用, (三)、其他阻塞:執行的執行緒執行sleep()或join()方法,或者發出了I/O請求時, 處理完畢時,執行緒重新轉入就緒狀態。
5)、死亡狀態(Dead):執行緒執行完了或者因異常退出了run()方法,該執行緒結束生命周 期。
當呼叫start方法的時候,該執行緒就進入就緒狀態。等待CPU進行排程執行,此時還沒有真正執行執行緒。
當呼叫run方法的時候,是已經被CPU進行排程,執行執行緒的主要任務。
50.onSaveInstanceState() 和 onRestoreInstanceState();
答: Activity的 onSaveInstanceState() 和 onRestoreInstanceState()並不是生命週期方法,它們不同於 onCreate()、onPause()等生命週期方法,它們並不一定會被觸發。當應用遇到意外情況(如:記憶體不足、使用者直接按Home鍵)由系統銷燬一個Activity時,onSaveInstanceState() 會被呼叫。但是當用戶主動去銷燬一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被呼叫。因為在這種情況下,使用者的行為決定了不需要儲存Activity的狀態。通常onSaveInstanceState()只適合用於儲存一些臨時性的狀態,而onPause()適合用於資料的持久化儲存。
另外,當螢幕的方向發生了改變, Activity會被摧毀並且被重新建立,如果你想在Activity被摧毀前快取一些資料,並且在Activity被重新建立後恢復快取的資料。可以重寫Activity的 onSaveInstanceState() 和 onRestoreInstanceState()方法。
版本控制是程式開發、管理必不可少的工具,特別是在多人協作的團隊中,適宜的版本控制工具可以提高開發效率,消除很多有程式碼版本帶來的問題
目前最流行的開源版本控制工具要數Subvision(SVN)、Git以及Mercurial(hg)了,其中SVN是集中式版本控制工具,Git和Mercurial則是分散式的。
早期常用的還有CVS
Github 是開原始碼庫以及版本控制系統
Git是一個開源的分散式版本控制系統,用以有效、高速的處理從很小到非常大的專案版本管理.
git是國外開源版本庫,不需要自己搭建伺服器,你在上面搭建上傳的工程程式碼都是公開的,誰都可以訪問,可以設定團隊成員分配修改的許可權。
如果要像SVN一樣指定的人可以訪問Git就需要收費了,SVN需要你有一臺伺服器,上面安裝SVN Server實現版本控制。
伺服器:
try {
ServerSocket server=new ServerSocket(8189);
Socket socket=server.accept();
String line;
BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter os=new PrintWriter(socket.getOutputStream());
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
System.out.println("客戶端:"+is.readLine());
line=sin.readLine();
while(!line.equals("bye")){
os.println(line);
os.flush();
System.out.println("伺服器:"+line);
System.out.println("客戶端:"+is.readLine());
line=sin.readLine();
}
os.close();
is.close();
socket.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
客戶端:
try {
//向本機的8189埠發出客戶請求
Socket socket=new Socket("127.0.0.1",8189);
//由系統標準輸入裝置構造BufferedReader物件
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
//由Socket物件得到輸出流,並構造PrintWriter物件
PrintWriter os=new PrintWriter(socket.getOutputStream());
//由Socket物件得到輸入流,並構造相應的BufferedReader物件
BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String readline;
readline=sin.readLine();//從系統標準輸入讀入字串
while(!readline.equals("bye")){
//將從系統標準輸入讀入的字串輸出到Server
os.println(readline);
//並重新整理輸出流,使Server馬上收到該字串
os.flush();
System.out.println("客戶端:"+readline);
//從Server讀出字串,並列印到標準輸出裝置上
System.out.println("伺服器端:"+is.readLine());
readline=sin.readLine();
}
os.close();
is.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
一個不帶limit 一個帶limit。mysql為例首先,連線資料庫,寫一條sql語句把你要查詢的信信息總量查找出來sql =” select count(*) from tb”;
設定每頁顯示條數int display=20;
然後,當前頁為int page=1;
在寫一句sql = “select * from tb limit “+dispaly*(page - 1)+”,”+display;
最後,在頁面顯示分頁資訊把當前頁傳回給分頁處理頁,一定要把相關的條件一起傳回去,用get方法傳值。
很多時候系統自帶的View滿足不了設計的要求,就需要自定義View控制元件。自定義View首先要實現一個繼承自View的類。新增類的構造方法,override父類的方法,如onDraw,(onMeasure)等。如果自定義的View有自己的屬性,需要在values下建立attrs.xml檔案,在其中定義屬性,同時代碼也要做修改。
Json本身沒有長度限制,對後臺程式來講,JSON就是一個字串
如果檔案過大的會變成String報錯,這時改成流來做就可以了。
xUtils 與 afinal 目前的主要區別:
afinal 的View註解要繼承FinalActivity, 如果要使用FragmentActivity或其他View自定義檢視就要對已有程式碼進行較大的改造,耦合太強,非常不方便,而xUtils使用靜態初始化方法。
xUtils對http模組進行了較大的重構,支援大檔案上傳,支援7種http謂詞,mutipart支援設定subType,下載支援302重定向...
OnScrollListener監聽
在以下兩個方法中做出判斷和處理:
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// 計算最後可見條目的索引
lastVisibleIndex = firstVisibleItem + visibleItemCount - 1;
// 所有的條目已經和最大條數相等,則移除底部的View
if (totalItemCount == MaxDateNum + 1) {
mListView.removeFooterView(moreView);
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// 當不滾動時
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
//判斷是否滾動到底部
if (view.getLastVisiblePosition() == view.getCount() - 1) {
adapter.count += 10;
adapter.notifyDataSetChanged();
int currentPage=adapter.count/10;
Toast.makeText(getApplicationContext(), "第"+currentPage+"頁", Toast.LENGTH_LONG).show();
}
}
}
1.JSON和XML的資料可讀性基本相同
2.JSON和XML同樣擁有豐富的解析手段
3.JSON相對於XML來講,資料的體積小
4.JSON與JavaScript的互動更加方便
5.JSON對資料的描述性比XML較差
6.JSON的速度要遠遠快於XML