java面试题9 牛客:不同的服务器之间,哪种通信方式是不可行的
在一個基于分布式的游戲服務器系統中,不同的服務器之間,哪種通信方式是不可行的()?
A管道 B消息隊列 C高速緩存數據庫 D套接字首先看到這道題我是懵逼的,我們分別介紹一下各個的概念
管道為運行在同一個JVM中的兩個線程提供了通信的能力。
在java中通信的雙方應該是運行在同一進程中的不同線程。
Java提供管道功能,實現管道通信的類有兩組:PipedInputStream和PipedOutputStream或者是PipedReader和PipedWriter。管道通信主要用于不同線程間的通信。
一個PipedInputStream實例對象必須和一個PipedOutputStream實例對象進行連接而產生一個通信管道。PipedOutputStream向管道中寫入數據,PipedIntputStream讀取PipedOutputStream向管道中寫入的數據。一個線程的PipedInputStream對象能夠從另外一個線程的PipedOutputStream對象中讀取數據。
Java NIO 管道是 2 個線程之間的單向數據連接。Pipe有一個 source 通道和一個 sink 通道。數據會被寫到 sink 通道,從 source 通道讀取。
這里是 Pipe 原理的圖示:
創建管道
通過Pipe.open()方法打開管道。例如:
Pipe pipe = Pipe.open();
向管道寫數據
要向管道寫數據,需要訪問 sink 通道。像這樣:
Pipe.SinkChannel sinkChannel = pipe.sink();通過調用 SinkChannel 的write()方法,將數據寫入SinkChannel, 像這樣:
String newData = "New String to write to file..." + System.currentTimeMillis(); ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); buf.put(newData.getBytes()); buf.flip(); while(buf.hasRemaining()) {sinkChannel.write(buf); }從管道讀取數據
從讀取管道的數據,需要訪問 source 通道,像這樣:
Pipe.SourceChannel sourceChannel = pipe.source();
調用 source 通道的read()方法來讀取數據,像這樣:
ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = sourceChannel.read(buf);read()方法返回的 int 值會告訴我們多少字節被讀進了緩沖區。
對于管道,有下面這幾種類型:
①普通管道(PIPE):通常有兩種限制,一是單工,即只能單向傳輸;二是血緣,即常用于父子進程間(或有血緣關系的進程間)。
②流管道(s_pipe):去除了上述的第一種限制,實現了雙向傳輸。
③命名管道(name_pipe):去除了上述的第二種限制,實現了無血緣關系的不同進程間通信。
顯然,要求是對于不同的服務器之間的通信,是要要求全雙工形式的,而管道只能是半雙工,雖然可以雙向,但是同一時間只能有一個方向傳輸,全雙工和半雙工的區別可以如下圖示理解
Java消息服務(Java Message Service,JMS)應用程序接口是一個Java平臺中關于面向消息中間件(MOM)的API,用于在兩個應用程序之間,或分布式系統中發送消息,進行異步通信。
點對點與發布訂閱最初是由JMS定義的。這兩種模式主要區別或解決的問題就是發送到隊列的消息能否重復消費(多訂閱)
消息隊列
一、定義
JMS規范目前支持兩種消息模式:點對點(point to point, queue)和發布/訂閱(publish/subscribe,topic)
1.1、點對點:Queue(隊列),不可重復消費
消息生產者生產消息發送到queue中,然后消息消費者從queue中取出并且消費消息。
消息被消費以后,queue中不再有存儲,所以消息消費者不可能消費到已經被消費的消息。Queue支持存在多個消費者,但是對一個消息而言,只會有一個消費者可以消費。
?
1.2、發布/訂閱:Topic(主題),可以重復消費
消息生產者(發布)將消息發布到topic(主題)中,同時有多個消息消費者(訂閱)消費該消息。和點對點方式不同,發布到topic的消息會被所有訂閱者消費。
支持訂閱組的發布訂閱模式:
發布訂閱模式下,當發布者消息量很大時,顯然單個訂閱者的處理能力是不足的。實際上現實場景中是多個訂閱者節點組成一個訂閱組負載均衡消費topic消息即分組訂閱,這樣訂閱者很容易實現消費能力線性擴展。可以看成是一個topic下有多個Queue,每個Queue是點對點的方式,Queue之間是發布訂閱方式。
2、區別
2.1、點對點模式
生產者發送一條消息到queue,一個queue可以有很多消費者,但是一個消息只能被一個消費者接受,當沒有消費者可用時,這個消息會被保存直到有 一個可用的消費者,所以Queue實現了一個可靠的負載均衡。
2.2、發布訂閱模式
發布者發送到topic的消息,只有訂閱了topic的訂閱者才會收到消息。topic實現了發布和訂閱,當你發布一個消息,所有訂閱這個topic的服務都能得到這個消息,所以從1到N個訂閱者都能得到這個消息的拷貝。
3、流行模型比較
傳統企業型消息隊列ActiveMQ遵循了JMS規范,實現了點對點和發布訂閱模型,但其他流行的消息隊列RabbitMQ、Kafka并沒有遵循JMS規范。
RabbitMQ
RabbitMQ實現了AQMP協議,AQMP協議定義了消息路由規則和方式。生產端通過路由規則發送消息到不同queue,消費端根據queue名稱消費消息。
RabbitMQ既支持內存隊列也支持持久化隊列,消費端為推模型,消費狀態和訂閱關系由服務端負責維護,消息消費完后立即刪除,不保留歷史消息。
(1)點對點
生產端發送一條消息通過路由投遞到Queue,只有一個消費者能消費到。
(2)多訂閱
當RabbitMQ需要支持多訂閱時,發布者發送的消息通過路由同時寫到多個Queue,不同訂閱組消費不同的Queue。所以支持多訂閱時,消息會多個拷貝。
Kafka
Kafka只支持消息持久化,消費端為拉模型,消費狀態和訂閱關系由客戶端端負責維護,消息消費完后不會立即刪除,會保留歷史消息。因此支持多訂閱時,消息只會存儲一份就可以了。但是可能產生重復消費的情況。
(1)點對點&多訂閱
發布者生產一條消息到topic中,不同訂閱組消費此消息。
java高速緩存數據庫
1.Cache(高速緩存)
?
作為個人計算機的日常使用者,你肯定聽說過這些名詞:Cache(高速緩存)、Memory( 內存)、Hard disk(硬盤)。它們都是數據存取單元,但存取速度卻有很大差異,呈依 次遞減的順序。對于CPU來說,它可以從距離自己最近的Cache高速地存取數據,而不是 從內存和硬盤以低幾個數量級的速度來存取數據。而Cache中所存儲的數據,往往是CPU 要反復存取的數據,有特定的機制(或程序)來保證Cache內數據的命中率(Hit Rate)
。因此,CPU存取數據的速度在應用高速緩存后得到了巨大的提高。
對于數據庫來說,廠商的做法往往是在內存中開辟相應的區域來存儲可能被多次存取的 數據和可能被多次執行的語句,以使這些數據在下次被訪問時不必再次提交對DBMS的請 求和那些語句在下次執行時不必再次編譯。
因為將數據寫入高速緩存的任務由Cache Manager負責,所以對用戶來說高速緩存的內容 肯定是只讀的。需要你做的工作很少,程序中的SQL語句和直接訪問DBMS時沒有分別,返 回的結果也看不出有什么差別。而數據庫廠商往往會在DB Server的配置文件中提供與C ache相關的參數,通過修改它們,可針對我們的應用優化Cache的管理。下圖是在Win2K 中配置MS Access數據源的界面,在"驅動程序"部分你可設置的頁超時和緩沖區大小就是 和Cache有關的參數。在后面的討論中,我將展示一個更復雜的數據庫,向你解釋Cache 對訪問數據庫性能的影響和如何尋找最優的配置方案。
?
2.Connection Pool(連接池)
?
池是一個很普遍的概念,和緩沖存儲有機制相近的地方,都是縮減了訪問的環節,但它 更注重于資源的共享。下圖展示了建立"調制解調器池"以共享調制解調器資源的VPN撥號
方案:
對于訪問數據庫來說,建立連接的代價比較昂貴,因此,我們有必要建立"連接池"以提 高訪問的性能。我們可以把連接當作對象或者設備,池中又有許多已經建立的連接,訪 問本來需要與數據庫的連接的地方,都改為和池相連,池臨時分配連接供訪問使用,結 果返回后,訪問將連接交還。
JDBC 1.0標準及其擴展中沒有定義連接池,而在JDBC 2.0標準的擴展中定義了與連接池 相關的接口。與接口對應的類由應用服務器廠商實現,你可在對服務器的管理過程中調 節某個數據庫連接池的參數。下圖簡略地描述了連接池的運行機制:
套接字
套接字(socket)為兩臺計算機之間的通信提供了一種機制,在 James Gosling 注意到 Java 語言之前,套接字就早已赫赫有名。該語言只是讓您不必了解底層操作系統的細節就能有效地使用套接字。多數著重討論 Java 編碼的書或者未涵蓋這個主題,或者給讀者留下很大的想象空間。本教程將告訴您開始在代碼中有效地使用套接字時,您真正需要知道哪些知識。我們將專門討論以下問題:
什么是套接字 它位于您可能要寫的程序的什么地方 能工作的最簡單的套接字實現 ― 以幫助您理解基礎知識 詳細剖析另外兩個探討如何在多線程和具有連接池環境中使用套接字的示例 簡要討論一個現實世界中的套接字應用程序
如果您能夠描述如何使用?java.net?包中的類,那么本教程對您來說也許基礎了點,雖然用它來提高一下還是不錯的。如果您在 PC 和其它平臺上使用套接字已經幾年,那么最初的部分也許會使您覺得煩。但如果您不熟悉套接字,而且只是想知道什么是套接字以及如何在 Java 代碼中有效地使用它們,那么本教程就是一個開始的好地方。
所以這里選A 我是歌謠,歡迎接受你的理解
文章僅個人理解,來在各大網站。如有不合理之處,歡迎吐槽。
閱讀目錄(置頂)(長期更新計算機領域知識)https://blog.csdn.net/weixin_43392489/article/details/102380691
閱讀目錄(置頂)(長期更新計算機領域知識)https://blog.csdn.net/weixin_43392489/article/details/102380882
閱讀目錄(置頂)(長期科技領域知識)https://blog.csdn.net/weixin_43392489/article/details/102600114
歌謠帶你看java面試題 https://blog.csdn.net/weixin_43392489/article/details/102675944
總結
以上是生活随笔為你收集整理的java面试题9 牛客:不同的服务器之间,哪种通信方式是不可行的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ui设计卡片阴影_UI设计形状和对象基础
- 下一篇: 如何进入游戏行业_进入设计行业