1.索引的作用?和它的優點缺點是什麼?
索引就一種特殊的查詢表,數據庫的搜索可以利用它加速對數據的檢索。它很類似與現實生活中書的目錄,不需要查詢整本書內容就可以找到想要的數據。索引可以是唯一的,創建索引允許指定單個列或者是多個列。缺點是它減慢了數據錄入的速度,同時也增加了數據庫的尺寸大小。一般唯一、不爲空、經常被查詢的字段適合建索引
ps:Mysql裏面有兩種數據庫引擎,一種是MyISAM,他用的是B樹,行級鎖。另一種Innodb 他是B+樹,支持行鎖表鎖,而索引的話默認最多16個,因爲不是創的越多越好,而b樹b+樹他們的數據結構來說,利用索引,就快速定位,不用的話,會一條一條查找,主鍵也是索引的另一種抽象。
2.請簡述什麼是集羣?
服務器集羣就是指將很多服務器集中起來一起進行同一種服務,在客戶端看來就象是隻有一個服務器。集羣可以利用多個計算機進行並行計算從而獲得很高的計算速度,也可以用多個計算機做備份,從而使得任何一個機器壞了整個系統還是能正常運行。一旦在服務器上安裝並運行了羣集服務,該服務器即可加入羣集。羣集化操作可以減少單點故障數量,並且實現了羣集化資源的高可用性。
3.字符串中有重複的內容去重 例如:abbccccaaddaggb–>abvadagb
原理是: 循環一遍字符串,然後從頭找每次循環一遍字符串,發現重複的去除,然後已經去重的字母,就不再加入循環了,比如第一個去完重,那就第二遍由第二個來遍歷,直到字母都去完重
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("c");
System.out.println("沒有去重前的數據爲>>>" + list.toString());
for (int i = 0; i < list.size() - 1; i++) {
for (int j = list.size() - 1; j > i; j--) {
if (list.get(j).equals(list.get(i))) {
list.remove(j);
}
}
}
System.out.println("去重後的數據爲>>>" + list.toString());
}
}
4.JAVA中使用final修飾符,對程序有哪些影響
● 修飾類
當用final修飾一個類時,表明這個類不能被繼承。也就是說,如果一個類你永遠不會讓他被繼承,就可以用final進行修飾。final類中的成員變量可以根據需要設爲final,但是要注意 final 類中的所有成員方法都會被隱式地指定爲final 方法。在使用 final 修飾類的時候,要注意謹慎選擇,除非這個類真的在以後不會用來繼承或者出於安全的考慮,儘量不要將類設計爲 final類。
● 修飾方法
被final修飾的方法將不能被子類覆蓋,主要用於:
把方法鎖定,以防任何繼承類修改它的含義。
在早期的Java實現版本中,會將final方法轉爲內嵌調用,所以效率能夠提升。
● 修飾變量
對於一個final變量,如果是基本數據類型的變量,則其數值一旦在初始化之後便不能更改;如果是引用類型的變量,則在對其初始化之後便不能再讓其指向另一個對象。當用 final 作用於類的成員變量時,成員變量(注意是類的成員變量,局部變量只需要保證在使用之前被初始化賦值即可)必須在定義時或者構造器中進行初始化賦值,而且final變量一旦被初始化賦值之後,就不能再被賦值了
String底層是被final修飾的,所以是不可變字符串
5.什麼叫對象持久化(object persistence),爲什麼要進行對象持久化?
持久化的對象,是已經存儲到數據庫或保存到本地硬盤中的對象,我們稱之爲持久化對象。爲了保存在內存中的各種對象的狀態(也就是實例變量,不是方法),並且可以把保存的對象狀態再讀出來。我們可以使用Java提供的序列化機制。
簡單說對象序列化是將對象狀態轉換爲可保持或傳輸的格式的過程。什麼情況下需要序列化:
● 當你想把的內存中的對象狀態保存到一個文件中或者數據庫中時候;
● 當你想用套接字在網絡上傳送對象的時候;
● 當你想通過RMI傳輸對象的時候;
對象要實現序列化,是非常簡單的,只需要實現Serializable接口就可以了。
ps:dubbo就需要先序列化,然後反序列化接收,然後redis和Hibernae都需要用到持久化概念
6. 髒讀、幻讀和不可重複讀 + 事務隔離級別
髒數據在臨時更新(髒讀)中產生。事務A更新了某個數據項X,但是由於某種原因,事務A出現了問題,於是要把A回滾。但是在回滾之前,另一個事務B讀取了數據項X的值(A 更新後),A回滾了事務,數據項恢復了原值。事務B讀取的就是數據項X的就是一個“臨時”的值,就是髒數據。
丟失更新:兩個事務同時更新一行數據,最後一個事務的更新會覆蓋掉第一個事務的更新,從而導致第一個事務更新的數據丟失,這是由於沒有加鎖造成的;
==髒讀:==就是指當一個事務正在訪問數據,並且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然後使用了這個數據。因爲這個數據是還沒有提交的數據,那麼另外一個事務讀到的這個數據是髒數據,依據髒數據所做的操作可能是不正確的。
ps:😋別人修改金額1000,但是沒提交事務回滾了,第二個人讀取到了修改完金額1000
不可重複讀:一個事務讀進一條記錄,另一個事務更改了這條記錄並提交完畢,這時候第一個事務再次讀這條記錄時,它已經改變了
ps:😋一個人讀自己的錢500,正要再存500的時候,再讀一遍發現錢只剩一百了,因爲,第二個人他取了400然後提交了事務,但是自己卻不知道第一遍讀的500是正確的還是這個100是正確,兩次值不一樣,最好辦法是一個事務加鎖,處理完,其他人才能進事務。
==幻讀:==是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,以後就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。
ps😋幻讀和不可重讀差不多一樣的問題,只是幻讀的重點在於新增或者刪除,不可重複讀的重點是修改 ,解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表
事務隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
讀未提交(read-uncommitted) | 是 | 是 | 是 |
不可重複讀(read-committed) | 否 | 是 | 是 |
可重複讀(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
mysql默認的事務隔離級別爲repeatable-read不是隔離級別越高越好,要考慮到效率問題,結合實際業務場景進行使用
7.Mybatis中#和$的區別?
● #相當於對數據加上雙引號,$相當於直接顯示數據(#會攔截sql先加上"",作用有點像parestatement預編譯)
● #將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:order by#user_id#,如果傳入的值是111,那麼解析成sql時的值爲order by"111",如果傳入的值是id,則解析成的sql爲order by “id”.
● user_id$,如果傳入的值是111,那麼解析成sql時的值爲order by user_id,如果傳入的值是id,則解析成的sql爲order by id.
這個太容易sql注入了,不建議使用
● #方式能夠很大程度防止sql注入,$方式無法防止Sql注入。
● $方式一般用於傳入數據庫對象,例如傳入表名.
ps✴️ 接受從用戶輸出的內容並提供給語句中不變的字符串,這樣做是不安全的。這會導致潛在的SQL注入攻擊,因此你不應該允許用戶輸入這些字段,或者通常自行轉義並檢查。
8.JDBC編程有哪些不足之處,MyBatis是如何解決這些問題的
● 數據庫鏈接創建、釋放頻繁造成系統資源浪費從而影響系統性能,使用數據庫鏈接池可解決此問題。解決:在SqlMapConfig.xml中配置數據鏈接池,使用連接池管理數據庫鏈接。
● Sql語句寫在代碼中造成代碼不易維護,實際應用sql變化的可能較大,sql變動需要改變java代碼。解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
● 向sql語句傳參數麻煩,因爲sql語句的where條件不一定,可能多也可能少,佔位符需要和參數一一對應。解決: Mybatis 自動將 java 對象映射至 sql 語句。
● 對結果集解析麻煩,sql 變化導致解析代碼變化,且解析前需要遍歷,如果能將數據庫記錄封裝成 pojo 對象解析比較方便。解決:Mybatis 自動將 sql 執行結果映射至 java 對象。
說白了,mybatis是一個優秀的orm框架,自動將pojo對象與數據庫進行映射關聯。
9.使用MyBatis的mapper接口調用時有哪些要求?
● Mapper接口方法名和mapper.xml中定義的每個sql的id相同
● Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql的parameterType的類型相同
● Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同
● Mapper.xml文件中的namespace即是mapper接口的類路徑。
ps:他底層是將mapper的namespace+id方法名當作一個map的key進行存起來,如果已經有存的直接返回這個,如果沒有,就會先存起來,而且通過namespace+方法名很容易找到那個mapper類
10.你真的瞭解OSI七層模型說說他們的功能?
這裏的話可以直接看我另一篇文章,通過需求分析來一步步解讀七層模型