1. 程式人生 > >一些小題

一些小題

java相關

6.String 的常用方法

   length() 求長度

   equals()

   trim()

   substring(int beginIndex,int endIndex)

    split()

6.淺談session實現原理(阿里面試題)

1.伺服器端的產生Session ID
2.伺服器端和客戶端儲存Session ID
3.從HTTP Header中提取Session ID(傳送的是一個COOKIC值)
4.根據Session ID從伺服器端的Hash中獲取請求者身份資訊

5介面和抽象類的區別;

語法層面上的區別

  1)抽象類可以提供成員方法的實現細節,而介面中只能存在public abstract 方法;

  2)抽象類中的成員變數可以是各種型別的,而介面中的成員變數只能是public static final型別的;

  3)介面中不能含有靜態程式碼塊以及靜態方法,而抽象類可以有靜態程式碼塊和靜態方法;

  4)一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。

設計層面來說;

    抽象類是對事物的抽象,即是對類的抽象,而介面是對行為的抽象,抽象是“是不是”的關係,介面是“具不具有”的關係,

  如果修改抽象類,那麼繼承此類的子類可以不用修改,如果修改介面的話,實現介面的類必須全部修改。

4.

  • java.lang:包含一些Java語言的核心類,如String、Math、Integer、System和Thread,提供常用功能。
  • java.awt:包含了構成抽象視窗工具集(abstract window toolkits)的多個類,這些類被用來構建和管理應用程式的圖形使用者介面(GUI)。
  • java.applet:包含applet執行所需的一些類。
  • java.net:包含執行與網路相關的操作的類。
  • java.io:包含能提供多種輸入/輸出功能的類。
  • java.util:包含一些實用工具類,如定義系統特性、使用與日期日曆相關的函式。

3.Model,封裝了應用程式的資料和有他們組成的pojo

  View,負責把模型資料放到檢視上,將資料以一定形式展現給使用者

  Controller,負責處理使用者請求,並建立適當的模型把他傳遞給檢視渲染

2。  java home:是指jdk所在目錄,

       path:是使得系統在任何目錄下都能能識別java命令

       classPath:是讓編輯器知道去哪裡載入編譯java檔案的時候 其所需的包和類,

1.java面試題之collection與collections區別:

   collection是一個介面介面介面。他抽取出各種集合<繼承List和Set>的主要功能,並做出統一行為規範。

他是很多集合的祖輩介面,沒錯父輩介面是List和Set。

Collections是一個工具類。工具類是工具,就像Math,Arrays類一樣,他是一種工具,集成了很多特定的功能。

比如排序,拷貝,替換,反轉等等等功能。工具類不能被例項化。 工具類使用方式:類名.方法名()

總體來說:collection是介面  , collections是工具類

eg:Collections.sort(list);   //把list按從小到大排序

補充一點:為什麼工具類不能被例項化?

工具類構造方法被private修飾了,所以不能new出來一個物件。

其中方法都是靜態方法,所以可以被直接用類名呼叫。

2.Java中==號與equals()方法的區別

== : 它的作用是判斷兩個物件的地址是不是相等。即,判斷兩個物件是不是同一個物件。(基本資料型別==比較的是值,引用資料型別==比較的是記憶體地址)

hashCode()的預設行為是對堆上的物件產生獨特值。如果沒有重寫hashCode(),則該class的兩個物件無論如何都不會相等

equals() : 它的作用也是判斷兩個物件是否相等。但它一般有兩種使用情況:

  • 情況1:類沒有覆蓋equals()方法。則通過equals()比較該類的兩個物件時,等價於通過“==”比較這兩個物件。
  • 情況2:類覆蓋了equals()方法。一般,我們都覆蓋equals()方法來兩個物件的內容相等;若它們的內容相等,則返回true(即,認為這兩個物件相等)。

eg:

public static void main(String[] args) {
        String a = new String("ab"); // a 為一個引用
        String b = new String("ab"); // b為另一個引用,物件的內容一樣
        String aa = "ab"; // 放在常量池中
        String bb = "ab"; // 從常量池中查詢
        if (aa == bb) // true
            System.out.println("aa==bb");
        if (a == b) // false,非同一物件
            System.out.println("a==b");
        if (a.equals(b)) // true
            System.out.println("aEQb");
        if (42 == 42.0) { // true
            System.out.println("true");
        }
    }

String s1="a"

String s2="b"

String s4="ab";

String s3=a1+s2相當於String s3=new String("ab");

所以 s3==s4//false

String 中intern()方法,該方法會先從常量池中查詢是否有該常量值,如果沒有則在常量池中建立,有則直接返回

eg:String s1="aa"  String s2=s1.intern(); s1==s2//true;

 

3.值傳遞(基本資料型別eg:整形,浮點型,布林型,字元型),引用傳遞(介面,類,陣列)

值傳遞是指物件被值傳遞,意味著傳遞了物件的一個副本,即使副本被改變,也不會影響源物件。(因為值傳遞的時候,實際上是將實參的值複製一份給形參。)

引用傳遞是指物件被引用傳遞,意味著傳遞的並不是實際的物件,而是物件的引用。因此,外部對引用物件的改變會反映到所有的物件上。(因為引用傳遞的時候,實際上是將實參的地址值複製一份給形參。)

public class yinyong {

    public static void main(String[] args){
        Person person = new Person();
        person.name="張三";
        System.out.println(person.name);
        change(person);
        System.out.println(person.name);

    }
    public static void change(Person person){
        //person=new Person();
        person.name="李四";
    }
}
class Person{
    public String name;
    Person(){
        this.name=name;
    }
}

集合相關

1.vector,ArrayList,LinkList

    (1)

vector ArrayList LinkList
執行緒安全 執行緒非安全 執行緒非安全
基於動態陣列實現的 基於動態陣列實現的 基於雙向連結串列實現的

 

 

長度超過預設值會增加100%                              長度超過預設值會增加50%(預設長度是10) .......................................
在多執行緒情況下使用 在隨機訪問多的時候用 在插入刪除多的時候用
     

 

 

 

 

 

 

list怎麼解決執行緒安全問題

List list = Collections.synchronizedList(new ArrayList());

2.三者區別   hashMap 原理、

HashMap Hashtable TreeMap
一般用於單執行緒(拉鍊法) 一般用於單執行緒(拉鍊法) 一般用於多執行緒(紅黑樹)
執行緒非安全 執行緒安全  
key、value都可以為null key、value都不可以為null(Hashtable的key或value,都不能為null!否則,會丟擲異常NullPointerException  
16 11  
     

 

開始學HashTable,HashMap和TreeMap的時候比較暈,覺得作用差不多,但是到實際運用的時候又發現有許多差別的。需要大家注意,在實際開發中以需求而定。

         java為資料結構中的對映定義了一個介面java.util.Map,而HashMap Hashtable和TreeMap就是它的實現類。Map是將鍵對映到值的物件,一個對映不能包含重複的鍵;每個鍵最多隻能對映一個一個值。

          Hashmap 是一個最常用的Map,它根據鍵的HashCode 值儲存資料,根據鍵可以直接獲取它的值,具有很快的訪問速度。HashMap最多隻允許一條記錄的鍵為Null;允許多條記錄的值為Null;HashMap不支援執行緒的同步,即任一時刻可以有多個執行緒同時寫HashMap;可能會導致資料的不一致。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力.

          Hashtable 與 HashMap類似,但是主要有6點不同。

         1.HashTable的方法是同步的,HashMap未經同步,所以在多執行緒場合要手動同步HashMap這個區別就像Vector和ArrayList一樣。   

        2.HashTable不允許null值,key和value都不可以,HashMap允許null值,key和value都可以。HashMap允許key值只能由一個null值,因為hashmap如果key值相同,新的key, value將替代舊的。   

        3.HashTable有一個contains(Object value)功能和containsValue(Object value)功能一樣。   

        4.HashTable使用Enumeration,HashMap使用Iterator。   

        5.HashTable中hash陣列預設大小是11,增加的方式是 old*2+1。HashMap中hash陣列的預設大小是16,而且一定是2的指數。   

        6.雜湊值的使用不同,HashTable直接使用物件的hashCode。

        TreeMap能夠把它儲存的記錄根據鍵排序,預設是按升序排序,也可以指定排序的比較器,當用Iterator 遍歷TreeMap時,得到的記錄是排過序的。

執行緒相關

1.啟動執行緒的方式:呼叫start()方法

2.start()和run() 的區別

總結:Thread和Runnable是實現java多執行緒的2種方式,runable是介面,thread是類,建議使用runable實現 java多執行緒,不管如何,最終都需要通過thread.start()來使執行緒處於可執行狀態。
下面我們來談談本文重點,start()和run()方法的區別
1) start:

通過t.start()啟動執行緒,JVM會自動呼叫該執行緒的run()方法

用start方法來啟動執行緒,真正實現了多執行緒執行,這時無需等待run方法體程式碼執行完畢而直接繼續執行下面的程式碼。通過呼叫Thread類的 start()方法來啟動一個執行緒,這時此執行緒處於就緒(可執行)狀態,並沒有執行,一旦得到cpu時間片,就開始執行run()方法,這裡方法 run()稱為執行緒體,它包含了要執行的這個執行緒的內容,Run方法執行結束,此執行緒隨即終止。

2) run:

run()方法只是類的一個普通方法而已,如果直接呼叫Run方法,程式中依然只有主執行緒這一個執行緒,其程式執行路徑還是隻有一條,還是要順序執行,還是要等待run方法體執行完畢後才可繼續執行下面的程式碼,這樣就沒有達到寫執行緒的目的。

總結:呼叫start方法方可啟動執行緒,而run方法只是thread的一個普通方法呼叫,還是在主執行緒裡執行。

這兩個方法應該都比較熟悉,把需要並行處理的程式碼放在run()方法中,start()方法啟動執行緒將自動呼叫 run()方法,這是由jvm的記憶體機制規定的。並且run()方法必須是public訪問許可權,返回值型別為void。

  1. 從執行結果肯明顯可以看出,使用start()方法具有非同步執行的效果,而使用run()方法是同步執行的效果,執行結果中規中矩。
  2. 使用start()方法,是真的啟動了相應的執行緒0-9,而使用run()方法並沒有真的啟動執行緒,而是由一個叫main的主執行緒去呼叫的run()方法。
  3. 所以,正確啟動執行緒的方式是使用start()方法。

==============================================================================

3.專案中涉及多執行緒的地方

轉載於雲棲社群

多執行緒是為了同步完成多項任務,不是為了提高執行效率,而是為了提高資源使用效率來提高系統的效率。執行緒是在同一時間需要完成多項任務的時候實現的。

 

問:能不能簡單描述一下你在java web開發中需要用到多執行緒程式設計的場景?

對多執行緒有些瞭解,但是不太清楚具體的應用場景,能簡單說一下你遇到的多執行緒程式設計的場景嗎?

回答一:

最典型的如:
1、使用者註冊完成送大禮包/積分之類,且積分等比較耗時;且這類任務即使失敗也不是特別重要的。
2、後臺執行緒:比如定期執行一些特殊任務,如定期更新配置檔案,任務排程(如quartz),一些監控用於定期資訊採集等。

回答二:

最典型的應用比如tomcat,tomcat內部採用的就是多執行緒,上百個客戶端訪問同一個web應用,tomcat接入後都是把後續的處理扔給一個新的執行緒來處理,這個新的執行緒最後呼叫到我們的servlet程式,比如doGet或者doPost方法。

如果不採用多執行緒機制,上百個人同時訪問一個web應用的時候,tomcat就得排隊序列處理了,那樣客戶端根本是無法忍受那種訪問速度的。

還有就是需要非同步處理的時候,需要使用多執行緒。比如task a和task b要並行處理,單個執行緒只能序列處理,先做完task a然後再做task b。如果想要多個task同時執行的話,就必須為每個task分配一個執行緒,然後通過java虛擬機器的執行緒排程,來同時執行多個任務。比如你的CPU是多核心的話,就可以讓一個CPU執行一個執行緒。如果只有一個CPU的話,底層是按照分時複用的原則,各個執行緒按照時間片來獲得CPU資源。

回答三:

特別耗時的操作,如備份資料庫,可以開個執行緒執行備份,然後執行返回,前臺不斷向後臺詢問執行緒執行狀態


問:JAVA專案中哪些場景需要用到多執行緒,深感迷茫,請使用過的高手指點。

答:


場景一:一個業務邏輯有很多次的迴圈,每次迴圈之間沒有影響,比如驗證1萬條url路徑是否存在,正常情況要迴圈1萬次,逐個去驗證每一條URL,這樣效率會很低,假設驗證一條需要1分鐘,總共就需要1萬分鍾,有點恐怖。這時可以用多執行緒,將1萬條URL分成50等份,開50個執行緒,沒個執行緒只需驗證200條,這樣所有的執行緒執行完是遠小於1萬分鐘的。

 

場景二:需要知道一個任務的執行進度,比如我們常看到的進度條,實現方式可以是在任務中加入一個整型屬性變數(這樣不同方法可以共享),任務執行一定程度就給變數值加1,另外開一個執行緒按時間間隔不斷去訪問這個變數,並反饋給使用者。

 

總之使用多執行緒就是為了充分利用cpu的資源,提高程式執行效率,當你發現一個業務邏輯執行效率特別低,耗時特別長,就可以考慮使用多執行緒。不過CPU執行哪個執行緒的時間和順序是不確定的,即使設定了執行緒的優先順序,因此使用多執行緒的風險也是比較大的,會出現很多預料不到的問題.這時候就牽扯到了多執行緒的併發問題.

wait and sleep 區別

   sleep,是Thread中的方法,呼叫sleep方法時不會釋放鎖,

   wait ,是Object 中的方法,呼叫wait方法時會釋放鎖,會把執行緒放到等待隊列當中,直到其他執行緒呼叫此物件的notify或notifyAll方法,

wait通常用於執行緒互動,sleep通常用於執行緒暫停

原子操作

原子操作是不可分割的操作,一個原子操作中是不會被其他執行緒所打斷的,所以不需要對原子操作同步,i++ 不是原子操作,因為他包含了對資料的讀取,修改,寫入,等

volatile 

換句話說,被volatile修飾的變數,能保證該變數的 單次讀或者單次寫 操作是原子的。

但是執行緒安全是兩方面需要的 原子性(指的是多條操作)和可見性。volatile只能保證可見性,synchronized是兩個均保證的。 
volatile輕量級,只能修飾變數;synchronized重量級,還可修飾方法。 
volatile不會造成執行緒的阻塞,而synchronized可能會造成執行緒的阻塞。

start() and run()

呼叫start()方法會新建一個執行緒,並且執行run裡面的方法,而直接呼叫run()方法,不會建立一個新的執行緒,只會當做一個普通方法

ThreadLocal

ThreadLocal是什麼呢?其實ThreadLocal並非是一個執行緒的本地實現版本,它並不是一個Thread,而是threadlocalvariable(執行緒區域性變數)。也許把它命名為ThreadLocalVar更加合適。執行緒區域性變數(ThreadLocal)其實的功用非常簡單,就是為每一個使用該變數的執行緒都提供一個變數值的副本,是Java中一種較為特殊的執行緒繫結機制,是每一個執行緒都可以獨立地改變自己的副本,而不會和其它執行緒的副本衝突。

========================================================================================

框架相關:

1.spring ioc:spring可以把物件之間的依賴關係轉而用配置檔案來管理,這就是其依賴注入機制,而這個注入關係在一個叫ioc容器中來管理,ioc就是可以動態的將一個物件所需的依賴注入給這個物件,而不用物件自己去new 一個自己所需的依賴,這就是我所理解的ioc

aop

2spring ioc初始化過程

   (1)Resource定位,(2)BeanDefinition的載入,(3)BeanDefinition的註冊

ioc 初始化過程

3.BeanFactory   applicationcontext區別?
1. BeanFactory負責讀取bean配置文件,管理bean的載入,例項化,維護bean之間的依賴關係,負責bean的宣告週期。

2. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,還提供了更完整的框架功能:
a. 國際化支援
b. 資源訪問:Resource rs = ctx. getResource(“classpath:config.properties”), “file:c:/config.properties”
c. 事件傳遞:通過實現ApplicationContextAware介面

3. 常用的獲取ApplicationContext

區別

1.BeanFactroy採用的是延遲載入形式來注入Bean的,即只有在使用到某個Bean時(呼叫getBean()),才對該Bean進行載入例項化,這樣,我們就不能發現一些存在的Spring的配置問題。而ApplicationContext則相反,它是在容器啟動時,一次性建立了所有的Bean。這樣,在容器啟動時,我們就可以發現Spring中存在的配置錯誤。 相對於基本的BeanFactory,ApplicationContext 唯一的不足是佔用記憶體空間。當應用程式配置Bean較多時,程式啟動較慢。

BeanFacotry延遲載入,如果Bean的某一個屬性沒有注入,BeanFacotry載入後,直至第一次使用呼叫getBean方法才會丟擲異常;而ApplicationContext則在初始化自身是檢驗,這樣有利於檢查所依賴屬性是否注入;所以通常情況下我們選擇使用 ApplicationContext。
應用上下文則會在上下文啟動後預載入所有的單例項Bean。通過預載入單例項bean ,確保當你需要的時候,你就不用等待,因為它們已經建立好了。

2.BeanFactory和ApplicationContext都支援BeanPostProcessor、BeanFactoryPostProcessor的使用,但兩者之間的區別是:BeanFactory需要手動註冊,而ApplicationContext則是自動註冊。(Applicationcontext比 beanFactory 加入了一些更好使用的功能。而且 beanFactory 的許多功能需要通過程式設計實現而 Applicationcontext 可以通過配置實現。比如後處理 bean , Applicationcontext 直接配置在配置檔案即可而 beanFactory 這要在程式碼中顯示的寫出來才可以被容器識別。 )

3.beanFactory主要是面對與 spring 框架的基礎設施,面對 spring 自己。而 Applicationcontex 主要面對與 spring 使用的開發者。基本都會使用 Applicationcontex 並非 beanFactory 。

@Before @After @Around @AfterReturning @AfterThrowing 的執行順序

四種通知的執行順序

=============================================================================================

mybatis相關

  1. mybatis 優缺點:

Mybatis的優點:

1、易於上手和掌握,提供了資料庫查詢的自動物件繫結功能,而且延續了很好的SQL使用經驗,對於沒有那麼高的物件模型要求的專案來說,相當完美。

2、sql寫在xml裡,便於統一管理和優化, 解除sql與程式程式碼的耦合。

3、提供對映標籤,支援物件與資料庫的orm欄位關係對映

4、 提供物件關係對映標籤,支援物件關係組建維護

5、提供xml標籤,支援編寫動態sql。

6、速度相對於Hibernate的速度較快

Mybatis的缺點:

1. SQL語句的編寫工作量較大,尤其是欄位多、關聯表多時,更是如此,對開發人員編寫SQL語句的功底有一定要求。

2. SQL語句依賴於資料庫,導致資料庫移植性差,不能隨意更換資料庫。

3、由於xml裡標籤id必須唯一,導致DAO中方法不支援方法過載。

4、物件關係對映標籤和欄位對映標籤僅僅是對對映關係的描述,具體實現仍然依賴於sql。

5、DAO層過於簡單,物件組裝的工作量較大。

6、不支援級聯更新、級聯刪除。

7、Mybatis的日誌除了基本記錄功能外,其它功能薄弱很多。

8、編寫動態sql時,不方便除錯,尤其邏輯複雜時。

9、提供的寫動態sql的xml標籤功能簡單,編寫動態sql仍然受限,且可讀性低。

2.mybatis 怎麼實現關聯表查詢

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 為這個mapper指定一個唯一的namespace,namespace的值習慣上設定成包名+sql對映檔名,這樣就能夠保證namespace的值是唯一的
例如namespace="me.gacl.mapping.classMapper"就是me.gacl.mapping(包名)+classMapper(classMapper.xml檔案去除字尾)
 -->
<mapper namespace="me.gacl.mapping.classMapper">
 
    <!-- 
        根據班級id查詢班級資訊(帶老師的資訊)
        ##1. 聯表查詢
        SELECT * FROM class c,teacher t WHERE c.teacher_id=t.t_id AND c.c_id=1;
        
        ##2. 執行兩次查詢
        SELECT * FROM class WHERE c_id=1;  //teacher_id=1
        SELECT * FROM teacher WHERE t_id=1;//使用上面得到的teacher_id
     -->
 
    <!-- 
    方式一:巢狀結果:使用巢狀結果對映來處理重複的聯合結果的子集
             封裝聯表查詢的資料(去除重複的資料)
        select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=1
    -->
    <select id="getClass" parameterType="int" resultMap="ClassResultMap">
        select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=#{id}
    </select>
    <!-- 使用resultMap對映實體類和欄位之間的一一對應關係 -->
    <resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" javaType="me.gacl.domain.Teacher">
            <id property="id" column="t_id"/>
            <result property="name" column="t_name"/>
        </association>
    </resultMap>
    
    <!-- 
    方式二:巢狀查詢:通過執行另外一個SQL對映語句來返回預期的複雜型別
        SELECT * FROM class WHERE c_id=1;
        SELECT * FROM teacher WHERE t_id=1   //1 是上一個查詢得到的teacher_id的值
    -->
     <select id="getClass2" parameterType="int" resultMap="ClassResultMap2">
        select * from class where c_id=#{id}
     </select>
     <!-- 使用resultMap對映實體類和欄位之間的一一對應關係 -->
     <resultMap type="me.gacl.domain.Classes" id="ClassResultMap2">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" column="teacher_id" select="getTeacher"/>
     </resultMap>
     
     <select id="getTeacher" parameterType="int" resultType="me.gacl.domain.Teacher">
        SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
     </select>
 
</mapper>