那些年遇到過的面試題

Java面試題整理html

一、SpringMVC的執行流程前端

  1. 用戶發送請求至前端控制器DispatcherServlet
  2. DispatcherServlet收到請求調用HandlerMapping處理器映射器。
  3. 處理器映射器找到具體的處理器,生成處理器對象及處理器攔截器(若是有則生成)一併返回給DispatcherServlet。
  4. DispatcherServlet調用HandlerAdapter處理器適配器
  5. HandlerAdapter通過適配調用具體的處理器(Controller,也叫後端控制器)。
  6. Controller執行完成返回ModelAndView
  7. HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet
  8. DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器
  9. ViewReslover解析後返回具體View
  10. DispatcherServlet根據View進行渲染視圖(即將模型數據填充至視圖中)。
  11. DispatcherServlet響應用戶

二、JVM內存溢出具體指哪些內存溢出?都會拋出什麼異常?java

  1. JVM管理兩種類型的內存,非堆。堆是在 Java 虛擬機啓動時建立的。簡單來講堆就是留給開發人員使用的;非堆就是JVM留給本身用的,運行期內GC不會釋放其空間。
  2. 堆內存的分配使用-Xms-Xmx兩個參數指定,默認值分別是系統內存的1/641/4。默認空餘堆內存小於 40%時,JVM就會增大堆直到-Xmx的最大限制;空餘堆內存大於70%時,JVM會減小堆直到-Xms的最小限制。所以服務器通常設置-Xms、 -Xmx相等以免在每次GC 後調整堆的大小。通常的要將-Xms-Xmx選項設置爲相同,而-Xmn1/4-Xmx值,建議堆的最大值設置爲可用內存的最大值的80%。堆的最大值受限於系統使用的物理內存。
  3. 非堆內存也叫永久保留區域,用於存放ClassMeta信息。

三、String類爲何是不可變類?面試

  • 緩存池
  • hashcode
  • 多線程中不肯定值

四、經常使用JVM設置參數有哪些?redis

  • -Xms 設置JVM最小可用內存
  • -Xmx 設置JVM最大可用內存
  • -Xmn 設置年輕代大小
  • -Xss 設置每一個線程的堆棧大小(在相同物理內存下,減少這個值能生成更多的線程。可是也不能無限生成,最多3000~5000個)
  • -XX:NewRatio 設置年輕代(包括Eden和兩個Survivor區)與年老代的比值。(設置爲4,則年輕代與年老代所佔比值爲1:4,年輕代佔整個堆棧的1/5)
  • -XX:SurvivorRatio 設置年輕代中Eden區與Survivor區的大小比值(設置爲4,則兩個Survivor區與一個Eden區的比值爲2:4,一個Survivor區佔整個年輕代的1/6)
  • -XX:MaxPermSize 設置持久代大小
  • -XX:MaxTenuringThreshold 設置垃圾最大年齡(若是設置爲0的話,則年輕代對象不通過Survivor區,直接進入年老代。對於年老代比較多的應用,能夠提升效率.若是將此值設置爲一個較大值,則年輕代對象會在Survivor區進行屢次複製,這樣能夠增長對象再年輕代的存活時間,增長在年輕代即被回收的概論)

五、談談Spring事物傳播特性算法

  • REQUIRED 若是存在一個事務,則支持當前事務。若是沒有事務則開啓一個新的事務
  • MANDATORY 支持當前事務,若是當前沒有事務,就拋出異常
  • NEVER以非事務方式執行,若是當前存在事務,則拋出異常
  • NOT_SUPPORTED 以非事務方式執行操做,若是當前存在事務,就把當前事務掛起
  • REQUIRES_NEW新建事務,若是當前存在事務,把當前事務掛起
  • SUPPORTS 支持當前事務,若是當前沒有事務,就以非事務方式執行
  • NESTED 支持當前事務,新增Save Point點,與當前事務同步提交或回滾。
    嵌套事務一個很是重要的概念就是內層事務依賴於外層事務。外層事務失敗時,會回滾內層事務所作的動做。而內層事務操做失敗並不會引發外層事務的回滾
  • NESTEDREQUIRES_NEW的區別 ?
    • 它們很是 相似,都像一個嵌套事務,若是不存在一個活動的事務,都會開啓一個新的事務。
    • 使用PROPAGATION_REQUIRES_NEW時,內層事務與外層事務就像兩個獨立的事務同樣,一旦內層事務進行了提交後,外層事務不能對其進行回滾。兩個事務互不影響。兩個事務不是一個真正的嵌套事務。同時它須要JTA 事務管理器的支持。
    • 使用PROPAGATION_NESTED時,外層事務的回滾能夠引發內層事務的回滾。而內層事務的異常並不會致使外層事務的回滾,它是一個真正的嵌套事務。

六、MySql索引的類型和實現方式?sql

七、Tomcat請求的處理流程?shell

八、如何防止Sql注入?數據庫

  • 最簡單的在登錄的時候用戶名填寫:‘or 1 = 1 –
  • 如何應對:
    • 參數化,禁止使用sql拼接
    • 對參數進行正則過濾
    • 過濾字符串中的關鍵字
    • 替換全部單引號
    • 能夠在前端使用js進行數據過濾

九、談談HashMap、ConcurrnetHashMapjson

  • HashMap

    • 非線程安全無序。在涉及到多線程併發的狀況,進行get操做有可能會引發死循環,致使CPU利用率接近100%。
    • 存儲null key和 null value
    • fail-fast機制,多線程修改會產生ConcurrentModificationException)
    • 解決方案有HashtableCollections.synchronizedMap(hashMap),不過這兩個方案基本上是對讀寫進行加鎖操做,一個線程在讀寫元素,其他線程必須等待,性能可想而知。
    • 單向鏈表數組
    • put方法
    • resize()方法,建立一個新Node數組,將原數組的元素複製到新的數組中;
    • hash碰撞如何解決(循環鏈表,在next節點上插入)
    • 爲了減小hash碰撞最好在初始化的時候預估數據的大小,在初始化的時候制定初始值
    • jdk1.8改爲了若是鏈表長度大於8就使用紅黑樹存儲
  • ConcurrnetHashMap 佔小狼的博客

    • 不容許null的key和value

    • Jdk1.7

      • 採用分段鎖的機制實現併發的更新操做,底層採用數組+鏈表的存儲結構。
      • 兩個核心靜態內部類 Segment和HashEntry;
      • Segment繼承ReentrantLock用來充當鎖的角色,每一個 Segment 對象守護每一個散列映射表的若干個桶;
      • HashEntry 用來封裝映射表的鍵 / 值對;
      • 每一個桶是由若干個 HashEntry 對象連接起來的鏈表。
    • jdk1.8

      • 拋棄了Segment分段鎖機制。利用CAS+Synchronized來保證併發更新的安全,底層採用數組+鏈表+紅黑樹的存儲結構;

      • Node[] table:默認爲null,初始化發生在第一次插入操做(initTable方法),默認大小爲16的數組,用來存儲Node節點數據,擴容時大小老是2的冪次方

      • nextTable:默認爲null,擴容時新生成的數組,其大小爲原數組的兩倍;

      • sizeCtl :默認爲0,用來控制table的初始化和擴容操做;

        • -1 表明table正在初始化
        • -N 表示有N-1個線程正在進行擴容操做
      • Node:保存keyvaluekeyhash值的數據結構。其中valuenext都用volatile修飾,保證併發的可見性。

        class Node<K,V> implements Map.Entry<K,V> {
            final int hash;
            final K key;
            volatile V val;
            volatile Node<K,V> next;
            ......
        }

        table初始化

        • 如何在併發執行initTable()方法的時候保證只執行一次的呢?
          • 經過Unsafe.compareAndSwapInt方法去修改sizeCtl的值爲-1,有且只有一個線程可以修改爲功,其它線程經過Thread.yield()讓出CPU時間片等待table初始化完成。

        put操做

        • 採用CAS+synchronized實現併發插入或更新操做
        • 根據spread方法計算hashcode值
        • 根據(n - 1) & hash 定位table數組索引位置
        • 獲取Unsafe.getObjectVolatile方法獲取table中對應的索引到元素f
        • 若是fnull,說明table中這個位置第一次插入元素,利用Unsafe.compareAndSwapObject方法插入Node節點。若是CAS成功,說明Node節點已經插入,隨後addCount(1L, binCount)方法會檢查當前容量是否須要進行擴容。若是CAS失敗,說明有其它線程提早插入了節點,自旋從新嘗試在這個位置插入節點。
        • 若是f的hash值爲-1,說明當前f是ForwardingNode節點,意味有其它線程正在擴容,則一塊兒進行擴容操做。
        • 其他狀況把新的Node節點按鏈表或紅黑樹的方式插入到合適的位置,這個過程採用同步內置鎖實現併發

十、JVM GC(minor gc,full gc)

JVM垃圾算法

  • 引用計數法(循環引用問題)
  • 可達性分析(思路就是經過一系列名爲GC Roots**的對象做爲起始點,從這些節點開始向下搜索,搜索所走過的路徑稱爲引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連時,則證實此對象是不可用的)。Java中能夠被做爲GC Roots中的對象有:
    • 虛擬機棧(棧楨中的本地變量表)中的引用的對象
    • 方法區中的類靜態屬性引用的對象
    • 方法區中的常量引用的對象
    • 本地方法棧中JNI(Native方法)的引用的對象

垃圾回收算法

  • 標記-清除算法(Mark-Sweep) 【會產生大量碎片】
  • 複製算法(Copying) 【內存被壓縮一半,效率低】
  • 標記-整理算法(Mark-Compact) 【將存活對象移向內存的一端。而後清除端邊界外的對象】
  • 分代收集算法(Generational Collection)
    • 新生代(複製算法,年齡>15就被移動到老生代中)
      • Eden
      • Survivor 0(From),Survivor 1(To)
      • Young GC ,也叫 Minor GC
      • 觸發條件:
        • 新生代採用「空閒指針」的方式來控制GC觸發,指針保持最後一個在新生代分配的對象位置,當有新的對象要分配內存時,用於檢查空間是否足夠,不夠就觸發GC
    • 老生代(標記-整理算法,通常通過2次以上標記)
      • Full GC ,也叫Major GC
      • 觸發條件:
        • 老生代空間不足(避免建立過大對象)
        • Pemanet Generation空間不足 (增大Perm Gen空間,避免太多靜態對象)
        • GC後晉升到老生代的平均大小大於老生代剩餘空間 (控制好新生代和舊生代的比例)
        • 手動調用System.gc();(垃圾回收不要手動觸發,儘可能依靠JVM自身的機制)

垃圾回收器

[參考文章]:

  1. 文章1
  2. 文章2

十一、什麼CAS,什麼是ABA問題,如何解決?

  • CAS(Compare and Swap),比較並交換,實現併發算法時經常使用到的一種技術
  • CAS的思想很簡單:三個參數,一個當前內存值V、舊的預期值A、即將更新的值B,當且僅當預期值A和內存值V相同時,將內存值修改成B並返回true,不然什麼都不作,並返回false。
  • 若是變量V初次讀取的時候是A,而且在準備賦值的時候檢查到它仍然是A。若是在這段期間曾經被改爲B,而後又改回A,那CAS操做就會誤認爲它歷來沒有被修改過。針對這種狀況,java併發包中提供了一個帶有標記的原子引用類AtomicStampedReference,它能夠經過控制變量值的版原本保證CAS的正確性。

十二、Spring中的IOC和AOP是如何實現的?

  • IOC是使用Java的反射機制實現的
  • AOP是根據動態代理機制實現的

1三、什麼是SpringBeans?

具體說來,它是被Spring框架容器初始化、配置和管理的對象。

1四、說說Dubbo的內部實現原理?

1五、瞭解Netty麼?

  • 不瞭解。。。

1六、說說什麼是NIO、AIO?

1七、經常使用的設計模式及好處?

  • 工廠模式
    • 客戶類和工廠類分開。消費者任什麼時候候須要某種產品,只需向工廠請求便可。
    • 缺點是當產品修改時,工廠類也要作相應的修改
  • 抽象工廠模式
    • 核心工廠類再也不負責全部產品的建立,而是將具體建立的工做交給子類去作。更抽象,更靈活。
  • 單例模式(double-check、靜態內部類、枚舉)
    • 全局只有一個實例,節省系統資源。全部的對象都訪問一個實例,保證了數據的安全性。
  • 適配器模式
    • 能夠屏蔽掉一些不須要關注的細節

1八、Java IO中常用的類?

1九、瞭解Java中的線程池麼?

20、Java中都有哪些鎖?

2一、MySql數據庫都有哪些引擎?它們的區別是什麼?

  • 經常使用的分爲InnoDB和MyISAM,區別以下:
    • 事物:InnoDB支持,MyISAM不支持
    • 外鍵:InnoDB支持,MyISAM不支持

2二、談談MySql索引的類型和實現方式?

  • 惟一索引 惟一索引是不容許其中任何兩行具備相同索引值的索引。當現有數據中存在重複的鍵值時,大多數數據庫不容許將新建立的惟一索引與表一塊兒保存。數據庫還可能防止添加將在表中建立重複鍵值的新數據。例如,若是在employee表中職員的姓(lname)上建立了惟一索引,則任何兩個員工都不能同姓。
  • 主鍵索引 數據庫表常常有一列或列組合,其值惟一標識表中的每一行。該列稱爲表的主鍵。 在數據庫關係圖中爲表定義主鍵將自動建立主鍵索引,主鍵索引是惟一索引的特定類型。該索引要求主鍵中的每一個值都惟一。當在查詢中使用主鍵索引時,它還容許對數據的快速訪問。
  • 彙集索引 在彙集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。一個表只能包含一個彙集索引。

2三、MySql慢查詢如何定位和優化?

2四、JVM內置了哪些垃圾回收器?

2五、什麼是Fail-Fast、Fail-Safe模式?

2六、說說ThreadLocal

2七、知道volatile關鍵字麼?

  • 內存可見性
  • 禁止指令重排
  • 不能保證原子性
  • 內存可見性:通俗來講就是,線程A對一個volatile變量的修改,對於其它線程來講是可見的,即線程每次獲取volatile變量的值都是最新的

  • 不能保證原子性

  • 操做普通變量的流程

    讀操做會優先讀取工做內存的數據,若是工做內存中不存在,則從主內存中拷貝一份數據到工做內存中;寫操做只會修改工做內存的副本數據,這種狀況下,其它線程就沒法讀取變量的最新值。

  • volatile關鍵字修飾的變量

    對於volatile變量,讀操做時JMM會把工做內存中對應的值設爲無效,要求線程從主內存中讀取數據;寫操做時JMM會把工做內存中對應的數據刷新到主內存中,這種狀況下,其它線程就能夠讀取變量的最新值。

2八、synchronized關鍵字

2九、使用過SpringCloud麼?

30、知道AQS(同步器)麼?

3一、Spring事物的隔離級別?

3二、MyBatis的執行流程?

3三、Linux經常使用命令

3四、Redis的數據類型、經常使用命令和使用場景?

  • Redis經常使用的數據類型有: StringListSetSorted SetHash
  • 操做KEY經常使用命令:
    • DEL key 若是存在刪除鍵
    • DUMP key 返回存儲在指定鍵的值的序列化版本
    • EXISTS key 此命令檢查該鍵是否存在
    • EXPIRE key seconds 指定鍵的過時時間
    • EXPIREAT key timestamp 指定的鍵過時時間。在這裏,時間是在Unix時間戳格式
    • PEXPIRE key milliseconds 設置鍵以毫秒爲單位到期
    • PEXPIREAT key milliseconds-timestamp 設置鍵在Unix時間戳指定爲毫秒到期
    • KEYS pattern 查找與指定模式匹配的全部鍵
    • MOVE key db 移動鍵到另外一個數據庫
    • PERSIST key 移除過時的鍵
    • PTTL key 以毫秒爲單位獲取剩餘時間的到期鍵。
    • TTL key 獲取鍵到期的剩餘時間。
    • RANDOMKEY 從Redis返回隨機鍵
    • RENAME key newkey 更改鍵的名稱
    • RENAMENX key newkey 重命名鍵,若是新的鍵不存在
    • TYPE key 返回存儲在鍵的數據類型的值。
  • String
    • 使用場景:普通單值存儲、JSON格式存儲、數字存儲
    • 經常使用命令:SETGETMSETMGETSETEXSETNXINCRINCRBYAPPEND
  • List 【雙向鏈表,列表的最大長度爲2^32 - 1,也即每一個列表支持超過40億個元素】
    • 使用場景:關注列表、粉絲列表。輕量級消息隊列,生產者push,消費者pop/bpop
    • 經常使用命令:
      • BLPOP
        BLPOP key1 [key2 ] timeout取出並獲取列表中的第一個元素,或阻塞,直到有可用
      • BRPOP
        BRPOP key1 [key2 ] timeout取出並獲取列表中的最後一個元素,或阻塞,直到有可用
      • BRPOPLPUSH
        BRPOPLPUSH source destination timeout從列表中彈出一個值,它推到另外一個列表並返回它;或阻塞,直到有可用
      • LINDEX
        LINDEX key index從一個列表其索引獲取對應的元素
      • LINSERT
        LINSERT key BEFORE|AFTER pivot value在列表中的其餘元素以後或以前插入一個元素
      • LLEN
        LLEN key獲取列表的長度
      • LPOP
        LPOP key獲取並取出列表中的第一個元素
      • LPUSH
        LPUSH key value1 [value2]在前面加上一個或多個值的列表
      • LPUSHX
        LPUSHX key value在前面加上一個值列表,僅當列表中存在
      • LRANGE
        LRANGE key start stop從一個列表獲取各類元素
      • LREM
        LREM key count value從列表中刪除元素
      • LSET
        LSET key index value在列表中的索引設置一個元素的值
      • LTRIM
        LTRIM key start stop修剪列表到指定的範圍內
      • RPOP
        RPOP key取出並獲取列表中的最後一個元素
      • RPOPLPUSH
        RPOPLPUSH source destination刪除最後一個元素的列表,將其附加到另外一個列表並返回它
      • RPUSH
        RPUSH key value1 [value2]添加一個或多個值到列表
      • RPUSHX
        RPUSHX key value添加一個值列表,僅當列表中存在
  • Hash【Redis Hash對應Value內部實際就是一個HashMap,這個Hash的成員比較少時Redis爲了節省內存會採用相似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構】
    • 使用場景:假設有多個用戶及對應的用戶信息,能夠用來存儲以用戶ID爲key,將用戶信息序列化爲好比json格式作爲value進行保存
    • 經常使用命令:
      • HDEL
      • HDEL key field[field...]刪除對象的一個或幾個屬性域,不存在的屬性將被忽略
      • HEXISTS
      • HEXISTS key field查看對象是否存在該屬性域
      • HGET
      • HGET key field獲取對象中該field屬性域的值
      • HGETALL
      • HGETALL key獲取對象的全部屬性域和值
      • HINCRBY
      • HINCRBY key field value將該對象中指定域的值增長給定的value,原子自增操做,只能是integer的屬性值可使用
      • HINCRBYFLOAT
      • HINCRBYFLOAT key field increment將該對象中指定域的值增長給定的浮點數
      • HKEYS
      • HKEYS key獲取對象的全部屬性字段
      • HVALS
      • HVALS key獲取對象的全部屬性值
      • HLEN
      • HLEN key獲取對象的全部屬性字段的總數
      • HMGET
      • HMGET key field[field...]獲取對象的一個或多個指定字段的值
      • HSET
      • HSET key field value設置對象指定字段的值
      • HMSET
      • HMSET key field value [field value ...]同時設置對象中一個或多個字段的值
      • HSETNX
      • HSETNX key field value只在對象不存在指定的字段時才設置字段的值
      • HSTRLEN
      • HSTRLEN key field返回對象指定field的value的字符串長度,若是該對象或者field不存在,返回0.
      • HSCAN
      • HSCAN key cursor [MATCH pattern][COUNT count]相似SCAN命令
    • Set
      • 使用場景:微博應用中,每一個用戶關注的人存在一個集合中,就很容易實現求兩我的的共同好友功能。
      • 經常使用命令:
        • SADD
        • SADD key member [member ...] 添加一個或者多個元素到集合(set)裏
        • SACRD
        • SCARD key獲取集合裏面的元素數量
        • SDIFF
        • SDIFF key [key ...]得到隊列不存在的元素
        • SDIFFSTORE
        • SDIFFSTORE destination key [key ...]得到隊列不存在的元素,並存儲在一個關鍵的結果集
        • SINTER
        • SINTER key [key ...]得到兩個集合的交集
        • SINTERSTORE
        • SINTERSTORE destination key [key ...]得到兩個集合的交集,並存儲在一個集合中
        • SISMEMBER
        • SISMEMBER key member肯定一個給定的值是一個集合的成員
        • SMEMBERS
        • SMEMBERS key獲取集合裏面的全部key
        • SMOVE
        • SMOVE source destination member移動集合裏面的一個key到另外一個集合
        • SPOP
        • SPOP key [count]獲取並刪除一個集合裏面的元素
        • SRANDMEMBER
        • SRANDMEMBER key [count]從集合裏面隨機獲取一個元素
        • SREM
        • SREM key member [member ...]從集合裏刪除一個或多個元素,不存在的元素會被忽略
        • SUNION
        • SUNION key [key ...]添加多個set元素
        • SUNIONSTORE
        • SUNIONSTORE destination key [key ...]合併set元素,並將結果存入新的set裏面
        • SSCAN
        • SSCAN key cursor [MATCH pattern] [COUNT count]迭代set裏面的元素

[參考連接]

3五、微服務中如何保證數據的一致性?

  • 一、同步事件服務,經過發送同步消息通知來保證
  • 二、異步事件服務
  • 三、外部事件服務(額外的網絡通訊)
  • 四、可靠事件通知(1. 事件的正確發送; 2. 事件的重複消費。)
  • 五、業務補償機制(數據一致性的時效性很低,多個服務經常可能處於數據不一致的狀況。)
  • 六、TCC(try、confirm、cancel)

3六、ZooKeeper的使用場景?

3七、經常使用數據結構及其實現?

3八、Docker/區塊鏈

3九、什麼狀況下會產生死鎖?

40、Redis有哪幾種數據淘汰策略?【redis 每服務客戶端執行一個命令的時候,會檢測使用的內存是否超額。若是超額,即進行數據淘汰。】

  1. volatile-lru:從已設置過時時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰
  2. volatile-ttl:從已設置過時時間的數據集(server.db[i].expires)中挑選將要過時的數據淘汰
  3. volatile-random:從已設置過時時間的數據集(server.db[i].expires)中任意選擇數據淘汰
  4. allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
  5. allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
  6. no-enviction(驅逐):禁止驅逐數據

4一、Redis一個字符串類型的值能存儲最大容量是多少?

  • 根據Redis官網的說法,應該是521MBMB。其他的(list、set、hash)都是2的32次方。

4二、Redis集羣方案應該怎麼作?都有哪些方案?

4三、消息隊列的實現原理?

4四、說說類的加載順序?

  1. 父類的static靜態代碼塊
  2. 子類的static靜態代碼塊
  3. 類內部變量
  4. 靜態成員類
  5. 普通成員類

4五、併發包下都用過哪些類?

4六、Redis持久化方式?

  • RDB(默認持久化方式,經過快照完成的。)
    • 當在指定時間內被更改的鍵的個數大於指定數值時就會進行快照。
    • 文件名是:dump.rdb
    • 可修改文件名和路徑
    • Save (阻塞其餘線程)
    • BGSave(fork方式,須要至少2倍的存儲空間用於複製)
  • AOF(將發送到Redis服務端的每一條命令都記錄下來,而且保存到硬盤中的AOF文件)
    • 系統每30秒同步一次
      • appendfsyncalways 每次都同步 (最安全可是最慢)
      • appendfsync everysec 每秒同步 (默認的同步策略)
      • appendfsyncno 不主動同步,由操做系統來決定 (最快可是不安全)
    • 默認的文件名是appendonly.aof
    • BGREWRITEAOF 重寫

4七、Linux下Redis安裝

  • mkdir -p /usr/local/src/redis
  • cd /usr/local/src/redis
  • wget http://download.redis.io/releases/redis-2.8.11.tar.gz
  • tar xzfredis-2.8.11.tar.gz
  • cdredis-2.8.11
  • make
  • makeinstall
  • 修改配置文件,使用redis後臺運行:
  • vi /etc/redis.conf
  • daemonize yes
  • 啓動
  • redis-server/etc/redis.conf

4八、Redis事物是如何實現的?

Redis事務一般會使用MULTI,EXEC,WATCH等命令來完成

watch指令在redis事物中提供了CAS的行爲。爲了檢測被watch的keys在是否有多個clients同時改變引發衝突,這些keys將會被監控。若是至少有一個被監控的key在執行exec命令前被修改,整個事物不執行任何動做,從而保證原子性操做,而且執行exec會獲得null的結果。

4九、Redis主從、集羣?

50、TCP/IP三次握手、四次揮手

5一、流量控制與滑動窗口?

5二、什麼狀況下索引會失效?

5三、什麼是動態代理,都有哪些方式?

5四、知道一致性hash麼?

5五、數據庫的鎖(行鎖,表鎖,頁級鎖,意向鎖,讀鎖,寫鎖,悲觀鎖,樂觀鎖,以及加鎖的select sql方式)

5六、Java的線程模型?

  • 使用一對一的線程模型實現的,一條Java線程就映射到一條輕量級進程之中。

  • Java線程調度:線程調度是指系統爲線程分配處理器使用權的過程

    • 協同式調度

      線程的執行時間由線程自己來控制,線程把本身的工做執行完了以後,要主動通知系統切換到另一個線程上。

    • 搶佔式調度(Java使用的線程調度方式就是搶佔式調度)

      那麼每一個線程將由系統來分配執行時間,線程的切換不禁線程自己來決定(在Java中,Thread.yield()可讓出執行時間,可是要獲取執行時間的話,線程自己是沒有什麼辦法的)

    • 線程優先級(1-10,可設置,不靠譜)

  • Java線程的狀態

    Java語言定義了5種線程狀態,在任意一個時間點,一個線程只能有且只有其中的一種狀態,這5種狀態分別以下。

    1. 新建(New):建立後還沒有啓動的線程處於這種狀態。

    2. 運行(Runable):Runable包括了操做系統線程狀態中的Running和Ready,也就是處於此狀態的線程有可能正在執行,也有可能正在等待着CPU爲它分配執行時間。

    3. 無限期等待(Waiting):處於這種狀態的線程不會被分配CPU執行時間,它們要等待被其餘線程顯式地喚醒。

      如下方法會讓線程陷入無限期的等待狀態:

    • 沒有設置Timeout參數的Object.wait()方法。

    • 沒有設置Timeout參數的Thread.join()方法。
    • LockSupport.park()方法。

      1. 限期等待(Timed Waiting):處於這種狀態的線程也不會被分配CPU執行時間,不過無須等待被其餘線程顯式地喚醒,在必定時間以後它們會由系統自動喚 醒。

    ​ 如下方法會讓線程進入限期等待狀態:

    • Thread.sleep()方法。

    • 設置了Timeout參數的Object.wait()方法。
    • 設置了Timeout參數的Thread.join()方法。
    • LockSupport.parkNanos()方法。
    • LockSupport.parkUntil()方法。

      1. 阻塞(Blocked):線程被阻塞了,「阻塞狀態」與「等待狀態」的區別是:「阻塞狀態」在等待着獲取到一個排他鎖,這個事件將在另一個線程放棄這個鎖的時候 發生;而「等待狀態」則是在等待一段時間,或者喚醒動做的發生。在程序等待進入同步區域的時候,線程將進入這種狀態。
      2. 結束(Terminated):已終止線程的線程狀態,線程已經結束執行。

5七、Java中如何序列化一個對象?

  • //序列化:
    ObjectOutputStream os = new ObjectOutputStream( new FileOutputStream("C:/wxp.txt")); 
    os.writeObject(user);
    os.close();
    //反序列化
    ObjectInputStream is = new ObjectInputStream( new FileInputStream("C:/wxp.txt"));  
    User temp = (User) is.readObject();

5八、Java中多態的實現機制?

  • 重寫Override是父類與子類之間多態性的一種表現
  • 重載Overload是一個類中多態性的一種表現.

5九、數據庫三範式是什麼?

答案一:

  • 一範式就是數據表中的每一列(字段),必須是不可拆分的最小單元,也就是確保每一列的原子性
  • 二範式就是要有主鍵,要求其餘字段都依賴於主鍵
  • 三範式就是要消除傳遞依賴,方便理解,能夠看作是「消除冗餘」。

答案二:

  • 第一範式(1NF):

    數據表中的每一列(字段),必須是不可拆分的最小單元,也就是確保每一列的原子性。

    例如: userInfo: '山東省煙臺市 1318162008' 依照第一範式必須拆分紅userInfo: '山東省煙臺市'   userTel: '1318162008'兩個字段

  • 第二範式(2NF):

    知足1NF後要求表中的全部列,都必需依賴於主鍵,而不能有 任何一列與主鍵沒有關係(一個表只描述一件事情)。例如:訂單表只能描述訂單相關的信息,因此全部的字段都必須與訂單ID相關。

    產品表只能描述產品相關的信息,因此全部的字段都必須與產品ID相關。所以在同一張表中不能同時出現訂單信息與產品信息。

  • 第三範式(3NF):

    知足2NF後,要求:表中的每一列都要與主鍵直接相關,而不是間接相關(表中的每一列只能依賴於主鍵)

    例如:訂單表中須要有客戶相關信息,在分離出客戶表以後,訂單表中只須要有一個用戶ID便可,而不能有其餘的客戶信息,由於其餘的用戶信息是直接關聯於用戶ID,而不是關聯於訂單ID。

查看知乎回答

60、數據庫ACID

  • 原子性
  • 一致性
  • 隔離性
  • 持久性

6一、Redis高級應用及技巧

Redis高級應用及技巧

6二、MyBatis原理

6三、MQ的原理

6四、Tomcat Server處理一個http請求的過程

假設來自客戶的請求爲:
http://localhost:8080/wsota/wsota_index.jsp
1) 請求被髮送到本機端口8080,被在那裏偵聽的Coyote HTTP/1.1 Connector得到
2) Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的迴應
3) Engine得到請求localhost/wsota/wsota_index.jsp,匹配它所擁有的全部虛擬主機Host
4) Engine匹配到名爲localhost的Host(即便匹配不到也把請求交給該Host處理,由於該Host被定義爲該Engine的默認主機)
5) localhost Host得到請求/wsota/wsota_index.jsp,匹配它所擁有的全部Context
6) Host匹配到路徑爲/wsota的Context(若是匹配不到就把該請求交給路徑名爲」"的Context去處理)
7) path=」/wsota」的Context得到請求/wsota_index.jsp,在它的mapping table中尋找對應的servlet
8) Context匹配到URL PATTERN爲*.jsp的servlet,對應於JspServlet類
9) 構造HttpServletRequest對象和HttpServletResponse對象,做爲參數調用JspServlet的doGet或doPost方法
10)Context把執行完了以後的HttpServletResponse對象返回給Host
11)Host把HttpServletResponse對象返回給Engine
12)Engine把HttpServletResponse對象返回給Connector
13)Connector把HttpServletResponse對象返回給客戶browser

6五、

  • ClassLoader
    - BootstrapClassLoader:加載jdk/jre/lib
    - ExtClassLoader:加載jdk/jre/lib/ext
    - AppClassLoader:負責加載用戶類路徑(ClassPath)所指定的類
    - 雙親委派:先由父類加載器加載,若是父類加載器不存在,那麼
    - 類的生命週期:加載、校驗、準備、解析、初始化、使用、卸載
    - 緩存:使用
    - 類加載機制:
    - 全盤負責,當一個類加載器負責加載某個Class時,該Class所依賴的和引用的其餘Class也將由該類加載器負責載入,除非顯示使用另一個類加載器來載入
    - 父類委託,先讓父類加載器試圖加載該類,只有在父類加載器沒法加載該類時才嘗試從本身的類路徑中加載該類
    - 緩存機制,緩存機制將會保證全部加載過的Class都會被緩存,當程序中須要使用某個Class時,類加載器先從緩存區尋找該Class,只有緩存區不存在,系統纔會讀取該類對應的二進制數據,並將其轉換成Class對象,存入緩存區。這就是爲何修改了Class後,必須重啓JVM,程序的修改纔會生效
    - 方法區和堆是全部線程共享的區域
  • JVM 內存模型
    - Java堆:存放對象實例
    - Java棧:Java方法執行的內存模型:每一個方法被執行的時候都會同時建立一個棧幀(Stack Frame)用於存儲局部變量表、操做棧、動態連接、方法出口等信息。每個方法被調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中從入棧到出棧的過程。
    - 方法區:用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據
    - 本地方法棧:本地方法棧則是爲虛擬機使用到的Native方法服務
    - 程序計數器:它的做用能夠看作是當前線程所執行的字節碼的行號指示器。
  • GC - 對象存活判斷 - 引用計數:沒法解決對象相互循環引用的問題 - 可達性分析 - GC算法:咱們經常使用的垃圾回收器通常都採用分代收集算法。 - 標記 -清除算法 - 複製算法 - 標記-壓縮算法 - 分代收集算法 - Eden, survivor
相關文章
相關標籤/搜索