c++ 单例模式_Java面试题总结之设计模式、网络基础、常用算法
一.設(shè)計模式
1.單例模式
A.懶漢式
- 單例模式最簡單的實現(xiàn)發(fā)現(xiàn),但是不支持多線程,線程不安全
- 如果想線程安全,在方法上加上synchronized就可以,不過這樣效率低下,99%情況都不會用到
B.餓漢式
線程安全,沒有加鎖所以效率高,但是類一加載就初始化,浪費內(nèi)存
public class Singleton { private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } private Singleton() { }}C.雙重鎖
安全且在多線程情況下能保持高性能
public class Singleton { private volatile static Singleton instance; public static Singleton getInstance(){ if(instance==null){ synchronized (Singleton.class){ if(instance==null){ instance = new Singleton(); } } } return instance; } private Singleton() { }}為什么加雙重驗證?
因為如果只有第一重驗證,線程A,B都通過第一重驗證,無論線程A,B哪個獲取到了鎖對象,對對象進行實例化,釋放鎖之后,另外一個線程也獲取鎖對象,也對對象進行實例化,此時,對象就不是單例的了。所以要加雙重驗證
為什么用要volatile修飾?
volatile主要是保證有序性,禁止重排序的,重排序是指編譯器和處理器為了優(yōu)化程序性能而對指令序列進行重新排序的一種手段,在創(chuàng)建對象的時候,也就是new對象的時候,是有三步的,分別是:
1.分配對象內(nèi)存空間
2.初始化對象
3.設(shè)置instance指向剛分配的內(nèi)存地址
不用volatile禁止重排序,順序就可能會變成
1.分配對象內(nèi)存空間
2.最后才初始化對象
當線程A獲取鎖因為重排序執(zhí)行順序變成1,3,2時,執(zhí)行到3后instance就不為null了,如果此時線程B判斷instance!=null,就直接返回了一個沒有初始化的對象了,這樣線程B有可能會造成程序崩潰
3.設(shè)置instance指向剛分配的內(nèi)存地址(此時對象還未初始化)
2.工廠模式
- 步驟:創(chuàng)建一個接口和實現(xiàn)幾個接口的實體類,再定義工廠類,之后就可以編寫測試類了,相較于抽象工廠模式簡單點
Color
public interface Color { void draw();}Green
public class Green implements Color { @Override public void draw() { System.out.println("Green..."); }}Yellow
public class Yellow implements Color { @Override public void draw() { System.out.println("Yellow..."); }}Red
public class Red implements Color { @Override public void draw() { System.out.println("Red..."); }}ColorFactory
public class ColorFactory { public Color getColor(String type){ if(type==null){ return null; } else if(type.equalsIgnoreCase("Yellow")){ return new Yellow(); }else if(type.equalsIgnoreCase("Red")){ return new Red(); }else if(type.equalsIgnoreCase("Green")){ return new Green(); } return null; }}測試類
public class ColorFactoryDemo { public static void main(String[] args) { ColorFactory factory = new ColorFactory(); Color yellow = factory.getColor("yellow"); yellow.draw(); }}3.抽象工廠模式
- 相較于工廠模式,較為復雜點
- 步驟:定義多個接口以及接口的實現(xiàn)類,編寫抽象工廠類,再編寫工廠類,工廠類都是擴展于抽象工廠類,然后再創(chuàng)建一個工廠生成器,之后就可以編寫測試類了
shape
public interface Shape { void draw();}Color
public interface Color { void fill();}Red
public class Red implements Color { @Override public void fill() { System.out.println("Red..."); }}Rectangle
public class Rectangle implements Shape { @Override public void draw() { System.out.println("Rectangle..."); }}AbstractFactory
public abstract class AbstractFactory { public abstract Shape getShape(String type); public abstract Color getColor(String type);}ColorFactory
public class ColorFactory extends AbstractFactory { @Override public Shape getShape(String type) { return null; } @Override public Color getColor(String type) { if(type==null){ return null; }else if(type.equalsIgnoreCase("Red")){ return new Red(); }else if(type.equalsIgnoreCase("Green")){ return new Green(); }else if(type.equalsIgnoreCase("Yellow")){ return new Yellow(); } return null; }}ShapeFactory
public class ShapeFactory extends AbstractFactory { @Override public Shape getShape(String type) { if(type==null){ return null; }else if(type.equalsIgnoreCase("Square")){ return new Square(); }else if(type.equalsIgnoreCase("Circle")){ return new Circle(); }else if(type.equalsIgnoreCase("Rectangle")){ return new Rectangle(); } return null; } @Override public Color getColor(String type) { return null; }}FactoryProduct
public class FactoryProduct { public static AbstractFactory getFactory(String factoryname){ if(factoryname.equalsIgnoreCase("Shape")){ return new ShapeFactory(); }else if(factoryname.equalsIgnoreCase("Color")){ return new ColorFactory(); } return null; }}測試類
public class AbstractFactoryDemo { public static void main(String[] args) { AbstractFactory shapeFactory = FactoryProduct.getFactory("Shape"); Shape rectangle = shapeFactory.getShape("Rectangle"); rectangle.draw(); AbstractFactory colorFactory = FactoryProduct.getFactory("Color"); Color red = colorFactory.getColor("Red"); red.fill(); }}二.網(wǎng)絡基礎(chǔ)
1.OSI七層模式從下到上哪七層
物理層、數(shù)據(jù)鏈路層、網(wǎng)絡層、傳輸層、會話層、表示層、應用層
2.TCP協(xié)議、ip協(xié)議、Http協(xié)議分別在哪一層
- 傳輸層(tcp、udp協(xié)議)
- 網(wǎng)絡層(ip協(xié)議)
- 應用層(Http協(xié)議)
3.TCP協(xié)議的3次握手過程
- 第一次握手:客戶端給服務器發(fā)送一個SYN報文
- 第二次握手:服務端收到客戶端發(fā)送的SYN報文,會回應一個SYN+ACK報文
- 第三次握手:客戶端收到SYN+ACK報文后,會回應一個ACK報文
服務端收到ACK報文后,三次握手建立完成,三次握手目的就是為了建立可靠的通信信道
4.TCP協(xié)議的4次揮手過程
- 假如是客戶端先發(fā)起關(guān)閉請求
- 第一次揮手:客戶端發(fā)送一個FIN報文,報文會指定一個序列號
- 第二次揮手:服務端收到FIN報文,會發(fā)送一個ACK報文,且把從客戶端接收到的序列號+1作為ACK報文的序列號,表明收到了客戶端的報文
- 第三次揮手:如果服務端也想斷開連接,和客戶端第一次揮手一樣,發(fā)送FIN報文,且指定一個序列號
- 第四次揮手:客戶端收到FIN報文后,一樣發(fā)送一個ACK報文作為應答,且把從服務端接收到的序列號+1作為自己ACK報文的序列號
- 服務端收到ACK報文后,就處于關(guān)閉狀態(tài)了
5.TCP和UDP區(qū)別
- TCP面向連接 UDP面向無連接的
- TCP傳輸可靠 UDP傳輸不可靠
- TCP傳輸速度慢 UDP傳輸速度快
- TCP偏重量級 UDP偏輕量級
- TCP面向字節(jié)流 UD面向報文(數(shù)據(jù)包)
6.http請求狀態(tài)碼
- 200 成功
- 302 重定向
- 404 請求資源不存在
- 4xx 客戶端錯誤
- 5xx 服務端錯誤
7.http和https區(qū)別
- http是明文傳輸,https是加密的安全傳輸
- http端口是80,https端口是443
8.簡述瀏覽器第一次訪問網(wǎng)頁情況
瀏覽器A在第一次請求服務器B的時候,服務器B會在服務端創(chuàng)建一個session,并為該瀏覽器A創(chuàng)建一個Cookie,并在響應時候把這個Cookie一同返回給瀏覽器A,這樣A在請求數(shù)據(jù)不變的情況下再次請求服務器B的時候會帶著這個Cookie,cookie中包含了sessionid,與服務端的session對應
9.cookie和session區(qū)別
- 兩者都是為了解決http協(xié)議無狀態(tài)的情況
- cookie是存放在瀏覽器上的,session放在服務器上的
- session依賴sessionid,而sessionid是存在cookie中的
- cookie放在本地,別人可以分析存放在本地的cookie進行cookie欺騙,所以安全性不如cookie
- 單個cookie保存數(shù)據(jù)不能超過4k,很多瀏覽器都限制一個站點最多保存20個cookie
10.get和post區(qū)別
- get請求在URL中傳送參數(shù)有長度限制,post則沒有
- get請求參數(shù)在URL可見,post請求參數(shù)不可見
- 從可見性上來看,post請求比起get請求安全的多
- get請求是可以緩存的,post請求不可以緩存(get一般是信息獲取之類的,post是信息修改添加之類的,所以get不需要每次獲取都去找數(shù)據(jù)庫)
11.重定向和轉(zhuǎn)發(fā)區(qū)別
- 重定向瀏覽器URL地址欄改變,轉(zhuǎn)發(fā)瀏覽器URL地址欄不變
- 重定向是兩次請求,轉(zhuǎn)發(fā)是一次請求
- 重定向后傳輸?shù)男畔G失(request),轉(zhuǎn)發(fā)傳輸?shù)男畔⒉粫G失
- 重定向速度不如轉(zhuǎn)發(fā)
轉(zhuǎn)發(fā)一般用于用戶登陸,根據(jù)角色轉(zhuǎn)發(fā)到相應的模塊
重定向一般用于用戶注銷登陸時返回主頁面和跳轉(zhuǎn)到其它的網(wǎng)站等
- 為什么說重定向是兩次請求,轉(zhuǎn)發(fā)是一次請求?
轉(zhuǎn)發(fā)過程:
用戶首先發(fā)送一個請求到服務端,服務端執(zhí)行servlet后,調(diào)用getRequestDispacther方法,把請求轉(zhuǎn)發(fā)給指定的xxx,整個流程都在服務端完成的,所以說轉(zhuǎn)發(fā)是一次請求
重定向過程:
用戶首先發(fā)送一個請求到服務端,服務端執(zhí)行servlet后,調(diào)用sendRedirect方法,這個方法是response,所以是向客戶端返回這個響應,響應告訴客戶端需要再發(fā)送一個請求,緊接著客戶端收到這個請求立即發(fā)出一個新的請求,去請求新的地址,這里兩個請求互不干擾,相互獨立,所以request會失效,所以說重定向是兩次請求
12.servlet和jsp區(qū)別
- jsp經(jīng)過編譯后就成為了Servlet
- jsp是java和html組成成一個擴展名為jsp的文件,所以jsp側(cè)重視圖
- servlet完全從表示層的html里分離開的,servlet側(cè)重控制邏輯(Servlet類似于Controller,用來做控制)
13.傳統(tǒng)api和restful api區(qū)別
傳統(tǒng)api是用URL來描述行為的(看URL就知道要干啥),不管成功失敗都會返回200和一段json,只是可能表示是錯誤的json
restfulapi是用HTTP方法描述行為,用URL描述資源,使用json交互數(shù)據(jù),使用HTTP狀態(tài)碼來表示不同的結(jié)果
14.jsp九大內(nèi)置對象和四大作用域
九大內(nèi)置對象:request、response、pageContext、session、application、out、config、page、exception
四大作用域:page(當前頁面有效)、request(當前請求有效)、session(當前會話有效)、application(當前應用有效)
三.常用算法
1.排序算法
A.選擇排序
B.冒泡排序
C.快速排序
2.手動實現(xiàn)一個ArrayList
最后
歡迎大家有興趣的可以關(guān)注我的公眾號【java小瓜哥的分享平臺】,文章都會在里面更新,還有各種java的資料都是免費分享的。
總結(jié)
以上是生活随笔為你收集整理的c++ 单例模式_Java面试题总结之设计模式、网络基础、常用算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: echarts tab切换_Python
- 下一篇: 游戏角色坐标的保存间隔_使用C++编写飞