使用wordpress版權(quán)深圳市seo上詞多少錢
unity操作問(wèn)題
-
位置:子物體的位置是相對(duì)于父物體的。如果你移動(dòng)父物體,子物體會(huì)保持相對(duì)于父物體的相對(duì)位置,跟著一起移動(dòng)。
-
旋轉(zhuǎn):子物體的旋轉(zhuǎn)也是相對(duì)于父物體的。旋轉(zhuǎn)父物體會(huì)導(dǎo)致子物體圍繞父物體的原點(diǎn)旋轉(zhuǎn)。
-
縮放:對(duì)父物體的縮放操作會(huì)按照相同的比例影響其所有子物體。這意味著如果父物體縮放2倍,所有子物體也會(huì)縮放2倍。
UI沒(méi)有變化,因?yàn)槭抢L(zhǎng)寬,和位置,只變化這兩個(gè)
Image的fill center是sole功能,就是要不要把中間的東西挖掉,是sliced 的image type獨(dú)有的挖心
inertia(伊娜莎baby)
Mask
組件的 Show Mask Graphic
屬性用于控制是否在屏幕上顯示蒙版的圖形。具體來(lái)說(shuō):
-
如果選中
Show Mask Graphic
:蒙版的圖形(如 Mask 組件的圖形)會(huì)被顯示出來(lái)。這通常用于調(diào)試或可視化蒙版區(qū)域,幫助開(kāi)發(fā)者理解蒙版如何影響子物體的顯示。 -
如果未選中
Show Mask Graphic
:蒙版的圖形不會(huì)被渲染出來(lái),只會(huì)顯示其影響下的子物體內(nèi)容。這通常是希望用戶只看到被蒙版內(nèi)容的效果,而不想看到蒙版本身的邊界。
Vertical Layout Group
Reverse Arrangement:
- 這個(gè)選項(xiàng)決定子物體排列的順序。如果勾選,子物體的順序會(huì)從最后一個(gè)元素到第一個(gè)元素進(jìn)行排列,效果是垂直方向上的反轉(zhuǎn)排列。
Child Force Expand (Width/Height):
這兩個(gè)默認(rèn)都勾了
為了就是個(gè)協(xié)調(diào),這個(gè)開(kāi)了之后Spacing上寫的就是假的了,
關(guān)了height force expand之后,?
Use Child Scale (Width/Height):
- 這兩個(gè)選項(xiàng)控制是否在布局時(shí)考慮子物體的縮放比例(
Scale
) 就是把不把子物體自己瞎調(diào)的Scale也照樣拿過(guò)來(lái)
?紅色的單獨(dú)改了縮放因子再拉進(jìn)來(lái)的,如果想整齊劃一,不想讓各個(gè)圖帶著莫名其妙的縮放進(jìn)來(lái)用,默認(rèn)兩個(gè)都不勾就很ok
這里只是調(diào)了width的縮放因子保持,和height是分開(kāi)的
?勾了width之后,會(huì)根據(jù)縮放因子進(jìn)行計(jì)算,使得圖片變得正常有序
height動(dòng)了比較怪
反正也是進(jìn)行某種算法,從而符合Layout Group對(duì)順序的安排
當(dāng)Vertical Layout Group
放在Scroll View
的Content
中時(shí),動(dòng)態(tài)創(chuàng)建圖片或其他UI元素時(shí),Content
的范圍會(huì)根據(jù)子物體的數(shù)量自動(dòng)擴(kuò)展。Vertical Layout Group
會(huì)自動(dòng)調(diào)整Content
的高度或?qū)挾?#xff0c;以容納所有的子物體。
但是沒(méi)有怎么回事?
可能是其中之一的原因
Content Size Fitter:確保
Content
對(duì)象上有Content Size Fitter
組件,并且其Vertical Fit
設(shè)置為Preferred Size
(如果是垂直滾動(dòng)),這樣才能根據(jù)子物體的大小自動(dòng)調(diào)整Content
的高度。Layout Element:檢查每個(gè)動(dòng)態(tài)創(chuàng)建的圖片(或UI元素)上有沒(méi)有不小心手賤加了
Layout Element然后亂改了布局屬性
。Vertical Layout Group 設(shè)置:
確保Vertical Layout Group
的Child Force Expand
選項(xiàng)適當(dāng)設(shè)置。Scroll View 的設(shè)置:檢查
Scroll Rect
組件,確保其與Content
正確關(guān)聯(lián)。如果Scroll Rect
未關(guān)聯(lián)或設(shè)置錯(cuò)誤,滾動(dòng)功能和Content
的擴(kuò)展可能會(huì)失效。
?
Content Size Fitter
的選項(xiàng)用于控制UI元素的尺寸調(diào)整方式,具體來(lái)說(shuō):
-
Unconstrained(無(wú)約束):表示該維度不會(huì)被
Content Size Fitter
修改,大小將保持不變,或者由其他組件(如Layout Element
)決定。 -
Min Size(最小大小):
Content Size Fitter
會(huì)將該維度的大小調(diào)整為所有子元素所需的最小值,確保它們能夠完全容納在這個(gè)大小中,但不會(huì)超過(guò)其最小需求。 -
Preferred Size(首選大小):
Content Size Fitter
會(huì)根據(jù)子元素的首選大小調(diào)整該維度。首選大小通常由子元素的內(nèi)容決定,比如文本的長(zhǎng)度或圖片的尺寸。這是最常用的選項(xiàng),用于動(dòng)態(tài)擴(kuò)展容器來(lái)適應(yīng)內(nèi)容。
Aspect Ratio Fitter
Aspect Ratio Fitter 是 Unity 中用于保持 UI 元素特定寬高比(Aspect Ratio)的組件。它主要用于確保某個(gè) UI 元素(比如圖片、視頻或其他內(nèi)容)的寬高比例在屏幕大小變化時(shí)保持一致。這樣可以避免元素被拉伸、壓縮或失真。
主要模式:
-
None:
- 不會(huì)根據(jù)寬高比進(jìn)行任何調(diào)整,UI 元素的寬高由其 RectTransform 控制。
-
Width Controls Height:
- 寬度固定,高度根據(jù)寬高比進(jìn)行動(dòng)態(tài)調(diào)整。例如,如果寬高比是 16:9,UI 元素的寬度為 160px,那么高度將自動(dòng)調(diào)整為 90px。
-
Height Controls Width:
- 高度固定,寬度根據(jù)寬高比動(dòng)態(tài)調(diào)整。例如,如果寬高比是 4:3,UI 元素的高度為 120px,那么寬度將自動(dòng)調(diào)整為 160px。
-
Fit In Parent:
- UI 元素會(huì)根據(jù)父對(duì)象的大小調(diào)整,同時(shí)保持寬高比,使其盡可能適應(yīng)父對(duì)象的大小而不失真。
-
Envelope Parent:
- UI 元素會(huì)完全覆蓋父對(duì)象的大小,同時(shí)保持寬高比,但有可能某些部分超出父對(duì)象的邊界。
使用場(chǎng)景:
- 當(dāng)你有圖片、視頻、或其他帶有固定比例的內(nèi)容,且需要在不同分辨率、屏幕大小變化時(shí)保持正確比例時(shí)非常有用。例如,處理頭像圖片、視頻播放器窗口時(shí),使用 Aspect Ratio Fitter 可以避免內(nèi)容失真。
?
?加了 Layout Element就可以直接修改各個(gè)布局屬性
還可以直接忽略layout,66
聊天室客戶端服務(wù)端部分記錄
老天,我腦子溢出
??????????????????????
c++的數(shù)組賦值問(wèn)題
c++里的數(shù)組所謂的“數(shù)組”,指的是傳入一個(gè)連續(xù)的存了數(shù)的內(nèi)存空間,然后通過(guò)[]來(lái)確定這一串內(nèi)存空間的切分方式, 也就是說(shuō)我的int arr[10];這個(gè)arr我完全可以賦值給int [][2],只不過(guò)是換了一種方式對(duì)這一段不變的內(nèi)存空間 進(jìn)行切分
void printArray(int arr[][2], int rows) {for (int i = 0; i < rows; ++i) {for (int j = 0; j < 2; ++j) {cout << arr[i][j] << " ";}cout << endl;}
}int main() {int myArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int (*ptr)[2] = (int (*)[2]) myArray; // 將一維數(shù)組的指針轉(zhuǎn)換為二維數(shù)組指針printArray(ptr, 5); // 傳入行數(shù)為 5return 0;
}
int arr2[][2]=myArray;可以嗎? ? NO
?int arr2[][2]=(int (*)[2])myArray;
int arr2[][2]=(int [][2])myArray; 那這樣呢
通通NO
都是想強(qiáng)轉(zhuǎn)類型,c++沒(méi)帶這種強(qiáng)轉(zhuǎn)
在 C++ 中,直接將一維數(shù)組賦值給二維數(shù)組的寫法 int arr2[][2] = (int (*)[2])myArray;
或 int arr2[][2] = (int [][2])myArray;
是不合法的。這是因?yàn)閿?shù)組的類型不匹配,編譯器無(wú)法自動(dòng)進(jìn)行這樣的轉(zhuǎn)換。
如果你想將一維數(shù)組的內(nèi)容視作一個(gè)二維數(shù)組,應(yīng)該手動(dòng)進(jìn)行轉(zhuǎn)換或使用指針。正確的方法是使用指針類型轉(zhuǎn)換,且要確保內(nèi)存布局的兼容性。
int myArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};// 將一維數(shù)組轉(zhuǎn)換為指向二維數(shù)組的指針int (*arr2)[2] = reinterpret_cast<int (*)[2]>(myArray);int myArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int (*ptr)[2] = (int (*)[2]) myArray; // 將一維數(shù)組的指針轉(zhuǎn)換為二維數(shù)組指針
在 C++ 中,以下的賦值方式是錯(cuò)誤的:
int (*ptr)[2] = (int [][2]) myArray;
這種方式無(wú)法直接將myArray
轉(zhuǎn)換為int[][2]
,因?yàn)?myArray
是一維數(shù)組,它的類型是int[10]
。這會(huì)導(dǎo)致類型不匹配。
int arr2[][2] = (int (*)[2]) myArray;
這也是不合法的,因?yàn)?arr2
需要在定義時(shí)指定大小,且類型不匹配。一開(kāi)始聲明的時(shí)候不帶[]里的數(shù),因?yàn)橛疫吚锶琴x值了的數(shù)據(jù),左邊自然硬氣了,可以直接數(shù)據(jù)類型猜測(cè)得出,但這也只是懶人不寫,正經(jīng)寫法就是在里面帶上具體數(shù)字,把數(shù)組聲明的明明白白的,
int arr2[5][2] = (int (*)[2]) myArray;
是非法的,因?yàn)槟阍噲D將一維數(shù)組的指針轉(zhuǎn)換為二維數(shù)組指針,而它們的內(nèi)存布局并不兼容。
數(shù)組維度:
myArray
是int[10]
,而arr2
是int[5][2]
。這兩者的內(nèi)存布局不同,因此不能直接互換。指針轉(zhuǎn)換:雖然你可以將
myArray
的首地址視為指向int[2]
的指針,但這并不改變?cè)紨?shù)組的結(jié)構(gòu),導(dǎo)致訪問(wèn)數(shù)據(jù)時(shí)的潛在錯(cuò)誤。為什么不能直接賦值
雖然二維數(shù)組和一維數(shù)組在內(nèi)存中都是連續(xù)存儲(chǔ)的,但它們的類型是不同的:
myArray
是一個(gè)一維數(shù)組,類型是int[10]
。arr2
是一個(gè)二維數(shù)組,類型是int[5][2]
。當(dāng)你嘗試將一維數(shù)組的指針轉(zhuǎn)換為二維數(shù)組指針時(shí)(如
int (*ptr)[2] = (int (*)[2]) myArray;
),在訪問(wèn)元素時(shí)會(huì)產(chǎn)生問(wèn)題。具體來(lái)說(shuō),二維數(shù)組的每一行都被視為一個(gè)int[2]
類型的數(shù)組,而直接將一維數(shù)組的首地址強(qiáng)制轉(zhuǎn)換成這樣的指針是邏輯上的錯(cuò)誤,因?yàn)榫幾g器并不知道你在訪問(wèn)時(shí)如何切割這段連續(xù)的內(nèi)存空間。意思就是,二維數(shù)組的確也是按照一整段連續(xù)的內(nèi)存空間存的,這點(diǎn)和一維數(shù)組一樣,
但是二維數(shù)組為二維,這一點(diǎn),導(dǎo)致每個(gè)下標(biāo)都有xy坐標(biāo)了
那么到底[][]左邊和右邊哪個(gè)是x哪個(gè)是y?
c++認(rèn)為這種數(shù)據(jù)排列方式在這個(gè)行列的邏輯問(wèn)題上,如果轉(zhuǎn)成一維的訪問(wèn)方式,可能存在數(shù)據(jù)錯(cuò)位的問(wèn)題
干脆就舍棄了各個(gè)維之間的轉(zhuǎn)換
// 目標(biāo)數(shù)組int copy[5][5];// 復(fù)制數(shù)組copyArray(grids, copy, 5, 5);// 函數(shù)定義
void copyArray(int src[5][5], int dest[5][5], int rows, int cols) {for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {dest[i][j] = src[i][j];}}
}
// 函數(shù)定義
int** copyArray(int arr[5][5], int rows, int cols) {// 動(dòng)態(tài)分配內(nèi)存int** newArr = new int*[rows];for (int i = 0; i < rows; i++) {newArr[i] = new int[cols];for (int j = 0; j < cols; j++) {newArr[i][j] = arr[i][j];}}return newArr;
}
在 C++ 中,二維數(shù)組的函數(shù)參數(shù)需要指定第二維的大小,但可以省略第一維的大小。這樣做是因?yàn)榫幾g器在編譯時(shí)能夠確定數(shù)組的內(nèi)存布局。
void copyArray(int src[][5], int dest[][5], int rows, int cols) {for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {dest[i][j] = src[i][j];}}
}
在這個(gè)例子中,int src[][5]
表示第一維的大小可以省略,但第二維的大小必須指定。原因是:
- 數(shù)組在內(nèi)存中是以行優(yōu)先的方式存儲(chǔ)的,編譯器需要知道每行的元素?cái)?shù)量,以正確計(jì)算元素的地址。
- 省略第一維:編譯器可以根據(jù)傳遞的數(shù)組推斷。
- 必須指定第二維:確保內(nèi)存布局的正確性,編譯器需要這個(gè)信息來(lái)正確訪問(wèn)元素。
-
數(shù)組參數(shù)的定義: 當(dāng)你定義一個(gè)二維數(shù)組參數(shù)時(shí),比如
void function(int arr[][5])
,這里的5
是必須的,因?yàn)榫幾g器需要知道每一行有多少列來(lái)正確地計(jì)算元素的內(nèi)存地址。 -
第一個(gè)維度的靈活性: 你可以不指定第一個(gè)維度,例如
void function(int arr[][5])
,因?yàn)榫幾g器在處理時(shí)能夠根據(jù)傳入的數(shù)組大小進(jìn)行推斷。 -
傳入的數(shù)組: 當(dāng)你將數(shù)組傳遞給函數(shù)時(shí),編譯器會(huì)根據(jù)第二個(gè)維度(這里是
5
)來(lái)解析數(shù)據(jù)。例如,如果你傳入一個(gè)大小為3x5
的數(shù)組,函數(shù)會(huì)處理這3
行、5
列的數(shù)組。 -
長(zhǎng)度限制: 傳入的數(shù)組的第一維(行數(shù))是可以任意的,只要你的數(shù)組在內(nèi)存中是連續(xù)的。你可以傳入任意大小的數(shù)組,但要確保第二個(gè)維度(列數(shù))與函數(shù)參數(shù)中定義的一致。
Java補(bǔ)充常用
StringBuilder
BigDecimal
SQL的多表查詢
-
hire_date DATE
:- 這個(gè)字段用于存儲(chǔ)員工的入職日期。
- 數(shù)據(jù)類型為
DATE
,表示它將只保存日期信息(年、月、日),不包含時(shí)間。
-
salary DECIMAL(10, 2)
:- 這個(gè)字段用于存儲(chǔ)員工的薪水。
- 數(shù)據(jù)類型為
DECIMAL
,表示這個(gè)字段可以存儲(chǔ)十進(jìn)制數(shù)字。 (10, 2)
表示總共有10位數(shù)字,其中2位是小數(shù)位。這意味著薪水的最大值可以達(dá)到99999999.99(即8位整數(shù)部分加上2位小數(shù)部分)。
-
gender ENUM('M', 'F')
:- 這個(gè)字段用于表示員工的性別。
- 數(shù)據(jù)類型為
ENUM
,表示這個(gè)字段只能取預(yù)定義的特定值。 - 在這里,
ENUM('M', 'F')
表示性別可以是'M'
(男性)或'F'
(女性),其他值將被拒絕。
創(chuàng)建表的巴拉巴拉
? ? customer_id INT PRIMARY KEY AUTO_INCREMENT,
? ? customer_name VARCHAR(50)
auto_increment自動(dòng)給加入值的數(shù)據(jù)行添加行,一個(gè)一個(gè)漲的唄
-- 創(chuàng)建訂單主表
CREATE TABLE OrderMaster (
? ? order_id INT PRIMARY KEY AUTO_INCREMENT,
? ? customer_id INT,
? ? order_date DATE,
? ? total_amount DECIMAL(10, 2),
? ? FOREIGN KEY (customer_id) REFERENCES Customer(customer_id)
);外鍵添加
foreign key(customer_id)references Customers(customer_id)
簡(jiǎn)簡(jiǎn)單單的,just like the plane finds a place to land,baby
查詢順序
在 SQL 查詢中,執(zhí)行的順序與書寫的順序并不相同,主要的執(zhí)行順序如下:
FROM
: 首先確定查詢的數(shù)據(jù)源,決定從哪個(gè)表中提取數(shù)據(jù)。JOIN
: 如果查詢涉及多個(gè)表,會(huì)在此步驟中進(jìn)行表的連接(如 INNER JOIN、LEFT JOIN 等)。WHERE
: 對(duì)數(shù)據(jù)進(jìn)行過(guò)濾,只保留滿足條件的行。GROUP BY
: 對(duì)結(jié)果進(jìn)行分組,通常與聚合函數(shù)(如 COUNT、SUM、AVG 等)一起使用。HAVING
: 對(duì)分組后的結(jié)果進(jìn)行進(jìn)一步的過(guò)濾,保留滿足條件的組。SELECT
: 從結(jié)果中選擇要顯示的列和計(jì)算的字段。ORDER BY
: 對(duì)結(jié)果集進(jìn)行排序。LIMIT
: 限制返回的行數(shù)。
GROUP_CONCAT
SELECT GROUP_CONCAT(employee_name) AS employees, hire_date
FROM Employee
GROUP BY hire_date
HAVING COUNT(*) > 1;
GROUP_CONCAT(employee_name)
是 MySQL 中的一個(gè)聚合函數(shù),用于將同一組中的多個(gè)值連接成一個(gè)字符串。具體來(lái)說(shuō),它將同一組內(nèi)的所有employee_name
字段的值合并為一個(gè)用逗號(hào)(或指定分隔符)分隔的字符串。
GROUP_CONCAT
的結(jié)果長(zhǎng)度有限制,最大為 1024 字符,可以通過(guò)設(shè)置group_concat_max_len
參數(shù)來(lái)調(diào)整。- 如果組內(nèi)有 NULL 值,
GROUP_CONCAT
會(huì)忽略這些 NULL 值。
?
表的左接,不是左邊的主表就是爹中之爹,如果右邊接過(guò)來(lái)的表有很多條訂單數(shù)據(jù),左邊的顧客表也會(huì)老老實(shí)實(shí)有多少條重復(fù)多少條,接來(lái)接去本質(zhì)還是為了結(jié)合盡量多的信息?
這里有四個(gè)客戶,如果只有三個(gè)人一起買了10件東西,
這里客戶表右接了訂單表,那么因?yàn)榭蛻舯頌橹鞅?#xff0c;打死都有顯示全里面的信息,
所以里面那個(gè)沒(méi)有下單的家伙最后也可以在接起來(lái)的表里找到
而因?yàn)槿齻€(gè)人買了10件東西,這三個(gè)人的客戶表行就會(huì)在大表里反復(fù)出現(xiàn),十次,每行自然是帶上了各自行的訂單信息
union
外部連接的回顧
在 SQL 中,外部連接用于返回符合條件的行,以及左表或右表中沒(méi)有匹配的行。根據(jù)連接的不同方式,有以下幾種情況:
- 左外連接 (LEFT JOIN):返回左表中的所有行,即使右表中沒(méi)有匹配的行。
- 右外連接 (RIGHT JOIN):返回右表中的所有行,即使左表中沒(méi)有匹配的行。
- 完整外部連接 (FULL OUTER JOIN):返回左表和右表中的所有行,匹配的行會(huì)顯示在一起,不匹配的行用
NULL
填充。
MySQL 對(duì)外部連接的支持
在 MySQL 中,完整外部連接并不直接支持。因此,我們使用 UNION
來(lái)模擬它。
UNION
的基本用法
UNION
用于合并兩個(gè)或多個(gè)查詢的結(jié)果集。合并的結(jié)果集去掉重復(fù)的行(如果想保留重復(fù)的行,可以使用 UNION ALL
)。
使用 UNION
模擬完整外部連接
當(dāng)我們想要獲取兩個(gè)表(在這個(gè)例子中是 Product
和 OrderDetail
)的完整外部連接時(shí),可以分別進(jìn)行左外連接和右外連接,然后使用 UNION
將兩個(gè)結(jié)果合并在一起。這樣,即使某個(gè)表沒(méi)有匹配的行,我們也會(huì)在結(jié)果中看到它。
很明顯union更加無(wú)腦,是純1+1
group by接兩個(gè)參
在 SQL 中,GROUP BY
子句用于將結(jié)果集中的行分組,從而對(duì)每個(gè)組應(yīng)用聚合函數(shù)(如 SUM
, COUNT
, AVG
等)。當(dāng)你使用 GROUP BY
時(shí),選擇的列必須是以下之一:
- 聚合函數(shù):如
SUM()
,COUNT()
,AVG()
,MAX()
,MIN()
等,表示對(duì)分組后的數(shù)據(jù)進(jìn)行匯總計(jì)算。 - 未被聚合的列:這些列必須出現(xiàn)在
GROUP BY
子句中,因?yàn)?SQL 需要知道如何將數(shù)據(jù)分組。
在這個(gè)例子中:
p.product_id
和p.product_name
是未被聚合的列,因此它們需要在GROUP BY
中列出。SUM(d.quantity)
和SUM(d.amount)
是聚合函數(shù),它們用于計(jì)算每個(gè)產(chǎn)品的總數(shù)量和總金額。
排序行為
- 在SQL中,
GROUP BY
并不會(huì)隱式地對(duì)結(jié)果集進(jìn)行排序。也就是說(shuō),雖然結(jié)果會(huì)按照p.product_id
和p.product_name
進(jìn)行分組,但不一定會(huì)按照這些列的值自動(dòng)排序。 - 如果你希望結(jié)果按照特定順序返回,需要使用
ORDER BY
子句明確指定排序規(guī)則。
?cross join
MySQL 支持交叉連接(CROSS JOIN)。在 MySQL 中,交叉連接返回兩個(gè)表的笛卡爾積,也就是說(shuō),結(jié)果集中會(huì)包含第一個(gè)表的每一行與第二個(gè)表的每一行的所有組合。交叉連接的語(yǔ)法相對(duì)簡(jiǎn)單,你可以通過(guò)以下兩種方式來(lái)實(shí)現(xiàn):
使用 CROSS JOIN
語(yǔ)法
SELECT * FROM TableA CROSS JOIN TableB;
使用 JOIN
語(yǔ)法(不帶條件)
你也可以使用 INNER JOIN
或 LEFT JOIN
語(yǔ)法,但不提供連接條件,結(jié)果將與 CROSS JOIN
相同:
SELECT * FROM TableA JOIN TableB; -- 省略 ON 條件,結(jié)果將是笛卡爾積
示例
假設(shè)有兩個(gè)表 Students
和 Courses
:
表: Students
student_id | student_name |
---|---|
1 | Alice |
2 | Bob |
表: Courses
course_id | course_name |
---|---|
101 | Math |
102 | Science |
如果你執(zhí)行以下交叉連接:
SELECT * FROM Students CROSS JOIN Courses;
結(jié)果將是:
student_id | student_name | course_id | course_name |
---|---|---|---|
1 | Alice | 101 | Math |
1 | Alice | 102 | Science |
2 | Bob | 101 | Math |
2 | Bob | 102 | Science |
現(xiàn)實(shí)應(yīng)用
交叉連接通常用于生成組合數(shù)據(jù),尤其在以下情況下:
-
組合選擇: 例如,如果你有多個(gè)產(chǎn)品和多個(gè)顧客,你可能想知道每個(gè)顧客對(duì)每個(gè)產(chǎn)品的反饋,交叉連接可以幫助你生成所有可能的組合。
-
報(bào)表生成: 在生成需要所有組合的報(bào)表時(shí),交叉連接可以有效提供所需的數(shù)據(jù)視圖。
不過(guò),使用交叉連接時(shí)要小心,因?yàn)槿绻砗艽?#xff0c;結(jié)果集可能會(huì)迅速增大,從而導(dǎo)致性能問(wèn)題。因此,在使用交叉連接時(shí),最好確保你真的需要所有的組合數(shù)據(jù)。
TCP
TCP(Transmission Control Protocol,傳輸控制協(xié)議)是互聯(lián)網(wǎng)通信中非常重要的協(xié)議,它負(fù)責(zé)保證設(shè)備之間的數(shù)據(jù)傳輸是可靠且有序的。TCP與IP(互聯(lián)網(wǎng)協(xié)議)一起,構(gòu)成了大家常說(shuō)的“TCP/IP協(xié)議棧”。在這個(gè)協(xié)議棧中,IP負(fù)責(zé)尋址和路由,而TCP負(fù)責(zé)數(shù)據(jù)傳輸?shù)目煽啃?/strong>。
TCP的基礎(chǔ)概念:
-
連接建立與關(guān)閉:
- 建立連接(握手):TCP在通信前會(huì)先通過(guò)一個(gè)三步的過(guò)程,叫做“三次握手”,來(lái)確保雙方已經(jīng)準(zhǔn)備好進(jìn)行數(shù)據(jù)傳輸。
- 第一次握手:客戶端發(fā)送一個(gè)連接請(qǐng)求(SYN)。
- 第二次握手:服務(wù)器收到請(qǐng)求,回應(yīng)(SYN + ACK)。
- 第三次握手:客戶端收到回應(yīng)后,確認(rèn)并完成連接(ACK)。
- 關(guān)閉連接(揮手):通信結(jié)束時(shí),通過(guò)“四次揮手”來(lái)安全關(guān)閉連接,確保所有數(shù)據(jù)都已經(jīng)傳輸完畢。
- 建立連接(握手):TCP在通信前會(huì)先通過(guò)一個(gè)三步的過(guò)程,叫做“三次握手”,來(lái)確保雙方已經(jīng)準(zhǔn)備好進(jìn)行數(shù)據(jù)傳輸。
-
數(shù)據(jù)可靠傳輸:
- 分片與重組:TCP會(huì)將大數(shù)據(jù)拆分成多個(gè)小數(shù)據(jù)包(稱為數(shù)據(jù)段)進(jìn)行傳輸,并且接收方在收到這些數(shù)據(jù)包后,會(huì)重新按照順序組合起來(lái)。
- 確認(rèn)機(jī)制:每個(gè)數(shù)據(jù)包發(fā)送后,接收方會(huì)發(fā)送一個(gè)確認(rèn)信息(ACK),告知發(fā)送方該數(shù)據(jù)已經(jīng)成功接收。如果發(fā)送方?jīng)]有收到確認(rèn)信息,就會(huì)重新發(fā)送這個(gè)數(shù)據(jù)包,確保數(shù)據(jù)不會(huì)丟失。
- 超時(shí)重傳:如果數(shù)據(jù)在一定時(shí)間內(nèi)沒(méi)有得到確認(rèn),TCP會(huì)重新發(fā)送數(shù)據(jù)包。
-
有序傳輸:
- 順序控制:TCP為每個(gè)數(shù)據(jù)包分配一個(gè)序列號(hào),接收方可以根據(jù)序列號(hào)把數(shù)據(jù)包按正確的順序拼接起來(lái),即使數(shù)據(jù)包到達(dá)的順序亂了,也能還原成正確的順序。
-
流量控制:
- 滑動(dòng)窗口:TCP會(huì)根據(jù)接收方的處理能力,動(dòng)態(tài)調(diào)整發(fā)送數(shù)據(jù)的速度。通過(guò)滑動(dòng)窗口機(jī)制,確保不會(huì)發(fā)送太多數(shù)據(jù)讓接收方處理不過(guò)來(lái),避免網(wǎng)絡(luò)擁塞。
-
擁塞控制:
- 網(wǎng)絡(luò)擁塞:如果網(wǎng)絡(luò)過(guò)于擁堵,TCP會(huì)自動(dòng)減少數(shù)據(jù)發(fā)送速度,防止加劇擁堵,保持網(wǎng)絡(luò)穩(wěn)定。
TCP的主要特點(diǎn):
- 可靠性:確保數(shù)據(jù)能夠完整、準(zhǔn)確地從發(fā)送方傳輸?shù)浇邮辗健?/li>
- 有序性:即使數(shù)據(jù)包的順序在傳輸過(guò)程中亂了,TCP仍能確保接收方能按照正確的順序組裝數(shù)據(jù)。
- 雙向通信:TCP是一種全雙工協(xié)議,允許雙方同時(shí)發(fā)送和接收數(shù)據(jù)。
- 流量控制與擁塞控制:能根據(jù)網(wǎng)絡(luò)狀況動(dòng)態(tài)調(diào)整數(shù)據(jù)發(fā)送速率,避免網(wǎng)絡(luò)擁堵。
CS和BS
兩種常見(jiàn)的軟件架構(gòu)模式
1. CS架構(gòu)(Client-Server架構(gòu))
要求客戶端(Client)和服務(wù)器(Server)各自具備一定的處理能力,
客戶端與服務(wù)器直接通信,共同完成任務(wù)。
應(yīng)用場(chǎng)景:
- 傳統(tǒng)的桌面應(yīng)用程序:像早期的聊天軟件、數(shù)據(jù)庫(kù)管理軟件等。
- 游戲客戶端:如很多在線游戲都采用了這種架構(gòu),客戶端負(fù)責(zé)顯示游戲畫面、處理用戶輸入,而服務(wù)器負(fù)責(zé)管理游戲狀態(tài)、同步多個(gè)玩家的操作。
優(yōu)點(diǎn):
- 客戶端和服務(wù)器可以分別優(yōu)化性能:客戶端側(cè)更注重用戶交互體驗(yàn),服務(wù)器端則關(guān)注數(shù)據(jù)處理和存儲(chǔ)的效率。
- 可以處理復(fù)雜的任務(wù)和大數(shù)據(jù)量的請(qǐng)求,因?yàn)榭蛻舳撕头?wù)器都有各自的處理能力。
缺點(diǎn):
- 客戶端程序需要安裝,維護(hù)和更新較為復(fù)雜。
- 客戶端與服務(wù)器緊密耦合,需要定期更新或修改客戶端軟件,以適應(yīng)服務(wù)器端的變化。
2. BS架構(gòu)(Browser-Server架構(gòu))
概念:
架構(gòu)的特點(diǎn)是瀏覽器(Browser)作為客戶端,與服務(wù)器進(jìn)行交互,通常依賴網(wǎng)頁(yè)技術(shù)(HTML、CSS、JavaScript)來(lái)實(shí)現(xiàn)用戶界面和功能。
結(jié)構(gòu):
- 瀏覽器(Browser):充當(dāng)客戶端,負(fù)責(zé)呈現(xiàn)界面、獲取輸入并與服務(wù)器交互。用戶不需要安裝額外的軟件,只要有瀏覽器即可使用。
- 服務(wù)器(Server):負(fù)責(zé)處理數(shù)據(jù)、執(zhí)行業(yè)務(wù)邏輯,并將處理后的結(jié)果通過(guò)網(wǎng)絡(luò)返回給瀏覽器。通常使用Web服務(wù)器,如Apache、Nginx等,數(shù)據(jù)庫(kù)、業(yè)務(wù)邏輯也通常在服務(wù)器端執(zhí)行。
工作方式:
- 用戶通過(guò)瀏覽器訪問(wèn)網(wǎng)站,瀏覽器發(fā)送請(qǐng)求到服務(wù)器,服務(wù)器處理請(qǐng)求后返回頁(yè)面或數(shù)據(jù),瀏覽器再將結(jié)果展示給用戶。
應(yīng)用場(chǎng)景:
- 網(wǎng)頁(yè)應(yīng)用程序:像電子郵件、社交媒體、在線購(gòu)物網(wǎng)站等。
- 輕量級(jí)應(yīng)用:不需要復(fù)雜的用戶界面或客戶端功能,用戶只需通過(guò)瀏覽器訪問(wèn)即可。
優(yōu)點(diǎn):
- 簡(jiǎn)化客戶端的安裝與維護(hù):用戶只需要一個(gè)瀏覽器即可使用應(yīng)用,不需要安裝復(fù)雜的客戶端程序。
- 跨平臺(tái)性強(qiáng):Windows、Mac、Linux,還是手機(jī)、平板,都能使用相同的服務(wù)。
- 易于更新與維護(hù):服務(wù)器端一旦更新,所有用戶都會(huì)即時(shí)獲取最新的服務(wù),無(wú)需對(duì)客戶端進(jìn)行頻繁更新。
缺點(diǎn):
- 由于依賴瀏覽器,無(wú)法處理非常復(fù)雜的用戶交互或計(jì)算任務(wù),性能可能不如CS架構(gòu)。
- 網(wǎng)絡(luò)依賴性較強(qiáng),離線使用受限。
3. CS與BS的對(duì)比
特點(diǎn) | CS架構(gòu) | BS架構(gòu) |
---|---|---|
客戶端程序 | 需要安裝專門的客戶端應(yīng)用程序 | 通過(guò)瀏覽器訪問(wèn),通常不需要安裝軟件 |
平臺(tái)依賴性 | 通常與操作系統(tǒng)或硬件緊密結(jié)合 | 跨平臺(tái)性強(qiáng),只需有瀏覽器即可使用 |
維護(hù)成本 | 客戶端需要定期更新和維護(hù) | 服務(wù)器更新后,用戶自動(dòng)獲得最新功能 |
用戶體驗(yàn) | 可提供復(fù)雜的界面和本地功能支持 | 受限于瀏覽器功能,復(fù)雜交互有限 |
數(shù)據(jù)處理 | 一部分邏輯在客戶端執(zhí)行 | 所有邏輯主要在服務(wù)器端處理 |
適用場(chǎng)景 | 大型應(yīng)用、桌面軟件、在線游戲 | 輕量級(jí)應(yīng)用、跨平臺(tái)應(yīng)用、網(wǎng)頁(yè)服務(wù) |
4. BS和CS架構(gòu)的選擇
- 選擇BS架構(gòu):當(dāng)你希望用戶通過(guò)瀏覽器訪問(wèn)你的應(yīng)用程序時(shí),比如開(kāi)發(fā)一個(gè)網(wǎng)頁(yè)應(yīng)用、內(nèi)容管理系統(tǒng)(CMS)、或是需要支持多平臺(tái)時(shí),BS架構(gòu)更為適合。
- 選擇CS架構(gòu):如果你開(kāi)發(fā)的應(yīng)用對(duì)性能、交互有更高的要求,比如一個(gè)桌面軟件、高性能游戲客戶端,或者需要更強(qiáng)的本地功能(如文件操作、設(shè)備訪問(wèn)),那么CS架構(gòu)會(huì)更合適。
未來(lái)趨勢(shì):
隨著瀏覽器技術(shù)和云服務(wù)的進(jìn)步,很多傳統(tǒng)的CS架構(gòu)應(yīng)用逐漸被轉(zhuǎn)移到BS架構(gòu)上,比如在線辦公軟件、云游戲等。這使得用戶體驗(yàn)和平臺(tái)支持得到了大幅提升,同時(shí)也減少了客戶端維護(hù)的負(fù)擔(dān)。
總結(jié)來(lái)說(shuō),CS架構(gòu)更加適合復(fù)雜任務(wù)和深度交互,而B(niǎo)S架構(gòu)則更適合輕量、跨平臺(tái)的應(yīng)用。選擇合適的架構(gòu)取決于應(yīng)用的需求、用戶的使用環(huán)境和開(kāi)發(fā)者的目標(biāo)。
TCP,CS,BS