安卓總結2

  • 1.怎么加速布局的繪制過程?

android3.0引入了硬件加速,他可以不用遍歷整個ViewTree來進行重繪,只重繪改變了的組件。
傳統(tǒng)的是通過draw()或者invalidate()方法通知屏幕刷新。
硬件加速的是將draw()方法里要繪制的圖形放入DisplayList中,當這個ViewTree的DisplayList全部記錄完成后,通過RootView中的DisplayList把改變的View,從新繪制。
分成四個級別:Appliction,Activity,Window,View

  • 2.談一談對象的生命周期?

java對象在虛擬機上分7個階段。
1.創(chuàng)建階段(分配空間,初始化工作)
2.應用階段(被引用持有)
3.不可見階段(沒有任何對象引用)
4.不可達階段(對象不再被任何強引用持有)
5.收集階段(GC已經(jīng)打算回收它)
6.終結階段(執(zhí)行完finalize()方法)
7.對象空間重新分配階段(GC回收該對象占用的空間)

  • 3 . java內(nèi)存回收機制?

最近分配的對象存放到年輕代,一段時間后,移動到年老代,最后還沒有被GC回收的話,進入永久代。
年輕代:復制算法進行gc回收
年老代:標記算法進行gc回收
永久代:存放靜態(tài)數(shù)據(jù)

  • 4 . 常見的內(nèi)存泄漏場景?

1)資源對象未關閉(File)
2)接口回調監(jiān)聽,在Activity類銷毀時,沒有取消注冊
3)靜態(tài)變量持有大量對象,沒有釋放。如將Bitmap放入靜態(tài)列表中,使用完沒有釋放。
4)非靜態(tài)內(nèi)部類 初始化為靜態(tài)對象,傳入了Activity的上下文。(可以使用Appliction上下文,或者在使用完外部引用對象時,釋放也可以)
5)Handler的使用。Handler通過發(fā)送Message與主線程進行交互,每一個Message發(fā)出后存儲在MessageQueue中,通過Looper進行輪詢處理消息。當Activity退出時,消息隊列只能中還有未處理的Message,Message持有handler實例的引用,handler又持有Activity的引用。最后導致activity無法被釋放。
解決辦法:
方法1:靜態(tài)Handler+持有對象使用弱引用。
方法2:Destory()時,移除消息隊列中的消息。

  • 5 . LruCache類的使用介紹?

最近最少使用緩存。內(nèi)部維護一個LinkedHashMap雙向鏈表,然后進行了線程安全的封裝。當數(shù)據(jù)被訪問時,它被放到隊列的尾部,當緩存將滿的時候,隊列頭部的值將被丟棄。android 官方推薦他作為圖片的內(nèi)存緩存工具。

  • 6 .請介紹一下Set接口和Map接口的關系?

他們都是java提高的集合類,但是Set接口是繼承Collection,Map沒有繼承。
Set類是不可以存放相同元素的集合。
Map類是存放鍵值對,key不可以相同。

  • 7 . HashMap和HashSet的關聯(lián)和區(qū)別?

HashSet實現(xiàn)了Set接口,它不允許集合中有重復對象,需要重新equals()和hashCode()方法,這樣才能比較對象的值是否相等。線程不安全的。
HashMap實現(xiàn)了Map接口,存放鍵值對,底層哈希表實現(xiàn)。允許鍵值對存null。線程不安全的。
Map集合是Set集合的擴展。
關系:
Map集合的key具有一個特征,所有的key不能重復,key之間沒有順序,將所有的key集中起來,就組成了一個Set集合,所以map集合提供了(Set<K> keySet()) 方法返回所有key組成的Set集合。

  • 8.Hash存儲機制的快速存取原理?

哈希表也叫散列表,它是基于快速存取角度設計的,是“空間換時間的”做法。

  • 9 . 線性表的理解?

它是從數(shù)據(jù)邏輯結構進行劃分中的一種,集合,線性結構,樹形結構,圖形結構。
線性結構主要就是線性表,非線性結構指的是樹和圖。
線性表是一對一的關系。分為順序實現(xiàn)和鏈式實現(xiàn),鏈式又分為單鏈表,循環(huán)鏈表,雙向鏈表。
List接口就是線性表,分為ArrayList和LinkedList現(xiàn)實。

  • 10.順序實現(xiàn)和鏈式實現(xiàn)的比較優(yōu)缺點?

順序表:空間性能上,因為存儲空間是靜態(tài)分布的,所有總有空間被浪費。時間性能上,邏輯順序和物理存儲順序一致,查找和讀取時高效。
鏈式表:空間性能上,存儲空間是動態(tài)分布的,所以不會有空間浪費,但是增加了節(jié)點,又增加了額外的空間。時間性能上,插入和刪除高效。

  • 11.棧和隊列的區(qū)別?

他們是特殊的線性表, 只提供了插入和刪除兩個功能。
棧:先進后出,棧頂插入和刪除。(鏈式棧更高效比順序棧)
隊列:先進先出,隊尾插入,隊頭刪除。

  • 12 . 排序
private static int[] nums = {21,30,48,32,16,9};
    //直接選擇排序 直接排序是進行n-1次處理 缺陷:每次只能確定一個最小的值
    //時間復雜度為o(n2) 每次找到最小的
    private static void fast() {
        int i ;
        int j ;
        int temp;
        try{
            for (i=0; i < nums.length ; i++){
                // j>i 完成排序的就不需要再排序
                for (j=nums.length-1 ; j > i ; j-- ){
                    if(nums[i] > nums[j]){
                        temp = nums[j];
                        nums[j] = nums[i];
                        nums[i] = temp;
                    }
                }
                System.out.println( Arrays.toString(nums));
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
    //冒泡排序  每次找到最大的
    private static void bubbleSort(){
        int temp,i,j;
        for (i=0 ; i < nums.length-1 ; i++){
            for (j = 0 ; j < nums.length-1-i ; j++){
                if(nums[j] > nums[j+1]){
                    temp = nums[j+1];
                    nums[j+1] = nums[j];
                    nums[j] = temp;
                    System.out.println( Arrays.toString(nums));
                }
            }
        }
    }
  • 13 .MeasureSpec類的介紹?

MeasureSpec是在onMeasure函數(shù)中測試大小的的類。它是一個32位的int值,高2位是測量模式,低32位是測量大小。
分為3種模式:
1.exactly :精確模式,100dp或者match_parent
2.at_most:最大模式,wrap_content。
3.unspecified:想多大就多大。

  • 14 .自定義View時為什么要重寫onMeasure方法?

view類默認的onMeasure()方法只處理exactly這一種模式,所以在自定義控件時,如果不重寫onMeasure()方法的話,就只有exactly這一種模式。
如果需要自定義組件支持wrap_content屬性,那么就要重寫onMeasure()方法。給View在wrap_content屬性下設置默認大小。不設置的話就是整個父組件大小。

  • 15 .自定義控件時為什么要重寫onMeasure()方法?

view:為了處理在wrap_fill情況下的,組件大小
viewGroup:對子View進行遍歷測量,來處理wrap_fill情況下自身的大小。

  • 16 .項目優(yōu)化?

分為兩部分,布局優(yōu)化和內(nèi)存優(yōu)化
布局優(yōu)化:
1)16ms繪制完成一個布局,會感覺流暢。
2)避免過度繪制浪費cpu和gpu資源。檢測工具“Enable GPU overdraw”
3)優(yōu)化布局層級
4)合理使用include,viewStub,merge
5)在theme中添加android:windowbackground="null";減少背景層級的繪制
6)使用9patch圖片
內(nèi)存優(yōu)化:
1)bitmap的優(yōu)化
2)代碼優(yōu)化,使用靜態(tài)檢測

  • 17 . hash算法為什么存取速度快?

它與線性表,樹,圖等結構不同,數(shù)據(jù)元素不存在邏輯關系,它只通過關鍵字與內(nèi)存地址有關聯(lián)。
散列技術是在記錄的存儲位置和它的關鍵字之間建立一個確定的對應關系f,使得每個關鍵字key 對應一個存儲位置f (key)。查找時,根據(jù)這個確定的對應關系找到給定值key 的映射f (key) ,若查找集合中存在這個記錄,則必定在f (key) 的位置上。這里我們把這種對應關系f 稱為散列函數(shù), 又稱為哈希(Hash) 函數(shù)。

  • 18 . List和Set的區(qū)別?

List:是順序表,可以存放相同元素。
Set:不可以存放相同元素。

  • 19 . 通過什么辦法保證Set列表中存放的元素是唯一的?

重寫 hashcode()和equal()方法。

  • 20 .Set接口的實現(xiàn)有哪些?他們有什么區(qū)別?

HashSet : 散列表存儲,高效讀取。
TreeSet:按照比較結果升序保存對象。元素必須實現(xiàn)Comparable接口。
LinkedHashSet:按照添加順序保存對象。

  • 21 .TreeSet是怎么對其中的元素進行排序的?

兩種辦法 自然排序和比較器排序。
自然排序:存放對象實現(xiàn)Comparerable<T>接口 ,并且重寫compareTo方法。
比較器排序:在TreeSet的構造函數(shù)中實現(xiàn)Comparator<T> 接口,重寫compare方法。
參考:http://blog.csdn.net/xiaofei__/article/details/53138681

  • 22 .List接口的實現(xiàn)有哪些?他們的比較?

ArrayList:擅長讀?。ň€性表結構)
LinkedList:擅長插入和刪除(鏈式存儲結構)

  • 23 .什么時候需要重寫hashcode和equal()方法?

當使用散列數(shù)據(jù)結構時(HashSet,HashMap等)。
兩個對象是否相等的規(guī)則是:
.1)判斷兩個對象的hashCode是否相等
如果不相等,認為兩個對象也不相等,完畢,如果相等,轉入2
.2)判斷兩個對象用equals運算是否相等
如果不相等,認為兩個對象也不相等
如果相等,認為兩個對象相等(equals()是判斷兩個對象是否相等的關鍵)
參考:http://blog.csdn.net/liushuai_ly/article/details/8197508

  • 24 .怎么程序一個好的程序?

1.健壯性
2.可擴展性
3.容錯性
4.穩(wěn)定性
5.可以從錯誤中恢復通過異常處理

  • 25 .異常處理的模型?

分為終止模型和恢復模型。
終止模型:拋出異常不做處理。
恢復模型:把try塊放在while循環(huán)里,這樣就不斷的進入try塊,直到得到滿意的結果。

  • 26 .對象的創(chuàng)建和銷毀優(yōu)化?

1)使用靜態(tài)工廠方法代替構造器創(chuàng)建實例。這樣不必在每次調用他們的時候都創(chuàng)建新的對象了。
2)多參數(shù)構造器時,使用建造者模式來創(chuàng)建對象。容易閱讀。
3)使用弱引用來處理緩存對象(有些抽象,可以網(wǎng)上查詢)

  • 27 .怎么停止一個線程?

通過設置標準位。

  • 28 .怎么處理滑動沖突?

可以通過外部攔截法,重寫父組件的onInterceptTouchEvent()方法,處理滾動事件,當x大于y的時候,返回true,對事件進行消費。其他情況下返回false就行了。

  • 29 .怎么提升app的啟動速度?

在 android monitors 中點擊cup模塊中的小鬧鐘開始,再次點擊停止。通過使用traceview可以得到哪些業(yè)務導致耗時操作。第三方初始化工作導致。
將第三方初始化工作放到服務中IntentService。

  • 30 .android中屬性動畫和補間動畫的區(qū)別?

補間動畫只是支持對View進行移動、縮放、旋轉和淡入淡出的操作,如果一旦需求超出了這四種操作,補間動畫就無能為力了,比如改變一個View的寬度。
補間動畫還有一個最大的缺陷,就是它只是改變了View的顯示效果而已,并不會真正的改變View的屬性。具體來說,例如屏幕左上角有一個Button,使用補間動畫將其移動到右下角,此刻你去點擊右下角的Button,它是絕對不會響應點擊事件的,因此其作用區(qū)域依然還在左上角。只不過是補間動畫將其繪制在右下角而已。

  • 31 .android提供的緩存策略是什么?

LruCache:內(nèi)存緩存類
DiskLruCache:存儲緩存類

  • 32.SlidingDrawer的使用?
  • 33.Activity給Fragment傳參數(shù)的方法?
 public static SellCarClueFragment getInstance(String clueproper) {
        SellCarClueFragment sellCarClueFragment = new SellCarClueFragment();
        Bundle bundle = new Bundle();
        bundle.putString("clueproper",clueproper);
        sellCarClueFragment.setArguments(bundle);
        return sellCarClueFragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if(getArguments()!=null){
            mClueproper = getArguments().getString("clueproper");
        }
        return super.onCreateView(inflater, container, savedInstanceState);
    }
  • 1.怎么加速布局的繪制過程?

android3.0引入了硬件加速,他可以不用遍歷整個ViewTree來進行重繪,只重繪改變了的組件。
傳統(tǒng)的是通過draw()或者invalidate()方法通知屏幕刷新。
硬件加速的是將draw()方法里要繪制的圖形放入DisplayList中,當這個ViewTree的DisplayList全部記錄完成后,通過RootView中的DisplayList把改變的View,從新繪制。
分成四個級別:Appliction,Activity,Window,View

  • 34.HashMap怎么根據(jù)Value刪除一項?
  • 35.RecycleView局部刷新?

1.notifyDataSetChanged()
2.notifyItemChanged(int postion)

  • 36.HorizontalScrollView與SeekBar沖突,怎么解決?

主要原因是HorizontalScrollView攔截了水平滑動的事件,你雖然修改了onTouchEvent,但是事件還是會被攔截。關于解決,給你提供兩個方向:
1、你可以重寫onInterceptTouchEvent,判斷當前觸摸的位置如果是SeekBar則不攔截;
2、在SeekBar的父容器中,進行判斷,如果當然觸摸是SeekBar,則請求不被攔截 getParent().requestDisallowInterceptTouchEvent(true);

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev){
       getParent().requestDisallowInterceptTouchEvent(true);
        return super.onInterceptTouchEvent(ev);
    }
  • 37.虛擬機

1)程序計數(shù)器(安全):當前線程所執(zhí)行的字節(jié)碼的行號指示器。
為了線程切換后能恢復到正確的執(zhí)行位置,每條線程都需要有一個獨立的程序計數(shù)器,各條線程之間計數(shù)器互不影響,獨立存儲,我們稱這類內(nèi)存區(qū)域為“線程私有”的內(nèi)存。
2)虛擬機棧(安全):它的生命周期與線程相同。
虛擬機棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法在執(zhí)行的同時都會創(chuàng)建一個 棧幀 用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。
也就是說,棧是由一個個棧幀組成。
3)本地方法棧(安全):給虛擬機棧的功能差不多
4)堆(不安全):Java堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機啟動時創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對象實例,幾乎所有的對象實例都在這里分配內(nèi)存。
Java堆是垃圾收集器管理的主要區(qū)域,因此很多時候也被稱做“GC堆”
5)方法區(qū)(不安全):方法區(qū)(Method Area)與Java堆一樣,是各個線程共享的內(nèi)存區(qū)域,它用于存儲已被虛擬機加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)。很多人都更愿意把方法區(qū)稱為“永久代”。
6)運行時常量池(不安全):是方法區(qū)的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池,用于存放編譯期生成的各種字面量和符號引用

  • 38.在虛擬機中,對象的創(chuàng)建是怎樣一個過程呢?

虛擬機遇到一條new指令時,首先將去檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用,并且檢查這個符號引用代表的類是否已被加載、解析和初始化過。如果沒有,那必須先執(zhí)行相應的類加載過程。
在類加載檢查通過后,接下來虛擬機將為新生對象分配內(nèi)存。對象所需內(nèi)存的大小在類加載完成后便可完全確定,為對象分配空間的任務等同于把一塊確定大小的內(nèi)存從Java堆中劃分出來。
分配內(nèi)存兩種方式,指針碰撞和空閑列表。
選擇哪種分配方式由Java堆是否規(guī)整決定,而Java堆是否規(guī)整又由所采用的垃圾收集器是否帶有壓縮整理功能決定。

1.HashMap:高速存取
2.LinkedHashMap:按照插入順序進行保存
3.TreeMap:可以根據(jù)鍵進行排序

  • 41 .可以向靜態(tài)方法中傳入Activity的上下文嗎?

分成兩個情況處理:

public class A{
    public static a(Activity activity){
        // do something
    }
}

public class B{
    private static Activity mActivity;
    public static b(Activity activity){
        mActivity = activity;
        // do something
    }
}

A中的靜態(tài)方法a,傳入了一個Activity對象,然后方法結束,Activity的引用activity生命周期結束,這樣不會造成泄露,沒問題。
B中的靜態(tài)方法b,傳入一個Activity對象,然后B的成員變量mActivity接收了這個引用。這個靜態(tài)成員變量會一直存在在進程中,這樣就會造成內(nèi)存泄露。
如果 class B 是一個靜態(tài)內(nèi)部類,非要持有 activity 的引用的話,可以考慮弱引用。
static class B {
    private WeakReference<Activirty> ref;
    
    public void setRef(Activity activity) {
        this.ref = new WeakReference<>(activity);
    }
    
    public void doSomething(){
        if (ref.get() != null){
            ref.get().doSomething();
        }
    }
}
  • 42 .類在jvm的是怎樣運行的?
/**
 * 線程私有的:
 * 程序計數(shù)器:代碼行號指示器
 * JVM棧 :每一個方法執(zhí)行時都會創(chuàng)建一個棧幀,用來保存局部變量+對象引用
 * Native棧 :處理底層本地方法
 *
 * 線程共享的:
 * 堆 : new 出來的對象(包括成員變量,不包括成員方法)+ 數(shù)組
 * 方法區(qū) (內(nèi)部包含常量池):類信息,常量,靜態(tài)變量 ,方法,編譯后代碼
 */
public class JvmUtil {
    private String name; //堆中
    //getName()進入方法區(qū)的常量池中
    private void getName(){
        String name; //局部變量 棧中
        /**
         * new SplashActivity() 堆中
         * activity 棧中
         */
        //當執(zhí)行到這行時,程序計數(shù)器進行保存行號
        SplashActivity activity = new SplashActivity(); 
    }
}
  • 43 .怎么檢查內(nèi)存泄漏問題?

http://m.blog.csdn.net/kong_gu_you_lan/article/details/74469041

  • 44 .什么是線性表?

線性表(元素關系一對一):
順序存儲結構:
1)存儲地址連續(xù)。
2)時間性能:查找O(1)、插入和刪除O(n)。
3)空間性能:需要預分配存儲空間,分大了浪費,小了容易發(fā)生上溢。
鏈式存儲結構:
1)任意的存儲單元。
2)時間性能:查找O(n)、插入和刪除O(1)。
3)空間性能:不需要分配存儲空間,只要有就可以分配,元素個數(shù)不受限制

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,885評論 11 349
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,351評論 25 708
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,853評論 18 399
  • 風從海上來,滿面桃花開。 我從媽媽的島中徐徐醒來。 邁步未來,滿身皚皚。 為你摘一片桃花,飄散在心心之海。 你不曾...
    我想有個項脊軒閱讀 345評論 0 2
  • (連載)《美夢如璇·第八章·第七十六節(jié)》 有習習的微風,有和煦的小陽光,有飄動的窗簾與光線 有溫度剛剛好的淡水,有...
    葉子程閱讀 253評論 1 0

友情鏈接更多精彩內(nèi)容