每日一句
如果你執(zhí)意追逐我的幻影,遲早會被真正的我打敗。
https://www.ylcoder.top/post/1649241412
概述
工作隊列(又稱任務隊列)的主要思想是避免立即執(zhí)行資源密集型任務,我們可以在安排任務之后再執(zhí)行。
我們把任務封裝為消息并將其發(fā)送到隊列奢入,在后臺運行的工作進程將彈出任務,并最終執(zhí)行作業(yè)媳叨。
當有多個工作線程時腥光,這些工作線程將一起處理這些任務关顷。
輪詢分發(fā)消息
在這里案例中我們會啟動兩個工作線程,一個消息發(fā)送線程
源碼:https://github.com/yltrcc/rabbitmq-demo/tree/master/demo2/src/main/java/com/yltrcc/demo
不公平分發(fā)
輪詢分發(fā)在某些場景下并不是很好武福。
例子:比如有兩個消費者在處理任務议双,其中有1個消費者1處理任務非常快捉片,另外一個消費者2處理速度很慢平痰。
這個時候采用輪詢分發(fā),速度快的消費者1很大部分時間處于空閑狀態(tài)伍纫,處理慢的消費者2一直在處理觉增。
這種情況下其實不太好,但是RabbitMQ不知道翻斟,它依然很公平的進行分發(fā)逾礁。
為了避免這種情況,我們可以設置參數(shù)
它的意思是:這個任務我還沒有處理完或者我還沒有應答你访惜,你先別分配給我嘹履,我目前只能處理一個任務,然后RabbitMQ就會把任務分配給沒有那么忙的那個空閑消費者债热。
當然如果所有的消費者都沒有完成手上的任務砾嫉,隊列還在不停的添加新任務,隊列有可能就會遇到隊列被撐滿的情況窒篱,這個時候就只能添加新的worker或者改變其他存儲任務的策略焕刮。
預取值
本身消息的發(fā)送就是異步發(fā)送的,所以在任何時候墙杯,channel 上肯定不止只有一個消息另外來自消費者的手動確認本質(zhì)上也是異步的配并。
因此這里就存在一個未確認的消息緩沖區(qū),因此希望開發(fā)人員能限制此緩沖區(qū)的大小高镐,以避免緩沖區(qū)里面無限制的未確認消息問題溉旋。
這個時候就可以通過使用** basic.qos 方法設置“預取計數(shù)”值來完成的。該值定義通道上允許的未確認消息的最大數(shù)量**嫉髓。一旦數(shù)量達到配置的數(shù)量观腊,
RabbitMQ 將停止在通道上傳遞更多消息,除非至少有一個未處理的消息被確認算行。
例如梧油,假設在通道上有未確認的消息 5、6州邢、7儡陨,8,并且通道的預取計數(shù)設置為 4,此時RabbitMQ 將不會在該通道上再傳遞任何消息迄委,除非至少有一個未應答的消息被 ack褐筛。
比方說 tag=6 這個消息剛剛被確認 ACK类少,RabbitMQ 將會感知這個情況到并再發(fā)送一條消息叙身。
消息應答和 QoS 預取值對用戶吞吐量有重大影響。通常硫狞,增加預取將提高向消費者傳遞消息的速度信轿。
面試題
String和StringBuilder、StringBuffer的區(qū)別残吩?
String是只讀字符串财忽,String 的底層是一個 char[] 通過final關(guān)鍵字進行修飾,所以說它的內(nèi)容是不能被改變的泣侮。
StringBuilder是Java 5中引入的即彪,它和StringBuffer的方法完全相同,
區(qū)別在于它是在單線程環(huán)境下使用的活尊,因為它的所有方面都沒有被synchronized修飾隶校,因此它的效率也比StringBuffer要高。
字符串的+操作其本質(zhì)是創(chuàng)建了StringBuilder對象進行append操作蛹锰,然后將拼接后的StringBuilder對象用toString方法處理成String對象深胳,
這一點可以用javap -c Test.class命令獲得class文件對應的JVM字節(jié)碼指令就可以看出。
Redis 怎么查看所有的key铜犬?
# 列出所有的key
redis> keys *
# 列出匹配的key
redis>keys apple*
1) apple1
2) apple2
LeetCode 3 無重復字符的最長子串
題目鏈接
https://leetcode-cn.com/problems/two-sum/
題目描述
給定一個字符串 s
舞终,請你找出其中不含有重復字符的 最長子串 的長度。
示例
示例 1:
輸入: s = "abcabcbb"
輸出: 3
解釋: 因為無重復字符的最長子串是 "abc"癣猾,所以其長度為 3敛劝。
示例 2:
輸入: s = "bbbbb"
輸出: 1
解釋: 因為無重復字符的最長子串是 "b",所以其長度為 1纷宇。
示例 3:
輸入: s = "pwwkew"
輸出: 3
解釋: 因為無重復字符的最長子串是 "wke"攘蔽,所以其長度為 3。
請注意呐粘,你的答案必須是 子串 的長度满俗,"pwke" 是一個子序列,不是子串作岖。
提示
0 <= s.length <= 5 * (10 ^ 4)
s 由英文字母唆垃、數(shù)字、符號和空格組成
題解
題解一:滑動窗口
用一個例子考慮如何在較優(yōu)的時間復雜度內(nèi)通過本題痘儡。
以示例一中的字符串a(chǎn)bcabcbb為例辕万,找出從每一個字符開始的,不包含重復字符的最長子串,那么其中最長的那個字符串即為答案渐尿。
對于示例一中的字符串醉途,我們列舉出這些結(jié)果,其中括號中表示選中的字符以及最長的字符串:
- 以 (a)bcabcbb 開始的最長字符串為 (abc)abcbb砖茸;
- 以 a(b)cabcbb 開始的最長字符串為 a(bca)bcbb隘擎;
- 以 ab(c)abcbb 開始的最長字符串為 ab(cab)cbb;
- 以 abc(a)bcbb 開始的最長字符串為 abc(abc)bb凉夯;
- 以 abca(b)cbb 開始的最長字符串為 abca(bc)bb货葬;
- 以 abcab(c)bb 開始的最長字符串為 abcab(cb)b;
- 以 abcabc(b)b 開始的最長字符串為 abcabc(b)b劲够;
- 以 abcabcb(b) 開始的最長字符串為 abcabcb(b)震桶;
如果我們依次遞增地枚舉子串的起始位置,那么子串的結(jié)束位置也是遞增的征绎!這里的原因在于蹲姐,假設我們選擇字符串中的第 k 個字符作為起始位置,并且得到了不包含重復字符的最長子串的結(jié)束位置為 r_k人柿。
那么當我們選擇第 k+1 個字符作為起始位置時柴墩,首先從 k+1 到 r_k的字符顯然是不重復的,并且由于少了原本的第 k 個字符顷扩,我們可以嘗試繼續(xù)增大 r_k拐邪,直到右側(cè)出現(xiàn)了重復字符為止。
這樣一來隘截,我們就可以使用「滑動窗口」來解決這個問題了:
- 我們使用兩個指針表示字符串中的某個子串(或窗口)的左右邊界扎阶,其中左指針代表著上文中「枚舉子串的起始位置」,而右指針即為上文中的 r_k婶芭;
- 在每一步的操作中东臀,我們會將左指針向右移動一格,表示 我們開始枚舉下一個字符作為起始位置犀农,然后我們可以不斷地向右移動右指針惰赋,但需要保證這兩個指針對應的子串中沒有重復的字符。在移動結(jié)束后呵哨,這個子串就對應著 以左指針開始的赁濒,不包含重復字符的最長子串。我們記錄下這個子串的長度孟害;
- 在枚舉結(jié)束后拒炎,我們找到的最長的子串的長度即為答案。
判斷重復字符
在上面的流程中挨务,我們還需要使用一種數(shù)據(jù)結(jié)構(gòu)來判斷 是否有重復的字符击你,常用的數(shù)據(jù)結(jié)構(gòu)為哈希集合(即 C++ 中的 std::unordered_set玉组,Java 中的 HashSet,Python 中的 set, JavaScript 中的 Set)丁侄。在左指針向右移動的時候惯雳,我們從哈希集合中移除一個字符,在右指針向右移動的時候鸿摇,我們往哈希集合中添加一個字符石景。
class Solution {
public int lengthOfLongestSubstring(String s) {
// 哈希集合,記錄每個字符是否出現(xiàn)過
Set<Character> occ = new HashSet<Character>();
int n = s.length();
// 右指針户辱,初始值為 -1鸵钝,相當于我們在字符串的左邊界的左側(cè)糙臼,還沒有開始移動
int rk = -1, ans = 0;
for (int i = 0; i < n; ++i) {
if (i != 0) {
// 左指針向右移動一格庐镐,移除一個字符
occ.remove(s.charAt(i - 1));
}
while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
// 不斷地移動右指針
occ.add(s.charAt(rk + 1));
++rk;
}
// 第 i 到 rk 個字符是一個極長的無重復字符子串
ans = Math.max(ans, rk - i + 1);
}
return ans;
}
}
復雜度分析
- 時間復雜度:O(N)O(N),其中 NN 是字符串的長度变逃。左指針和右指針分別會遍歷整個字符串一次必逆。
- 空間復雜度:O(∣Σ∣),其中 Σ 表示字符集(即字符串中可以出現(xiàn)的字符)揽乱,∣Σ∣ 表示字符集的大小名眉。在本題中沒有明確說明字符集,因此可以默認為所有 ASCII 碼在[0,128) 內(nèi)的字符凰棉,即 ∣Σ∣=128损拢。我們需要用到哈希集合來存儲出現(xiàn)過的字符,而字符最多有 ∣Σ∣ 個撒犀,因此空間復雜度為O(∣Σ∣)福压。
你好,我是yltrcc或舞,日常分享技術(shù)點滴荆姆,歡迎關(guān)注我:ylcoder