亚洲欧美日韩国产成人|亚洲中文字幕无码中字|HEYZO在线无码综合|久久久不卡精品国产一区二|久久精品亚洲无中文东京热|中文字幕乱码一区三区免费|亚洲国产欧美在线观看片不卡|国产精品久久一区二区三区97

怎么可以錯過(時間復雜度o1的算法有哪些)時間復雜度為o1的算法,你永遠無法理解時間 (四)編程復雜度:時間表示與運算,400大寫,

保健品 nanfang 2023-12-26 02:27 160 0

1.時間復雜度是o(1)的算法

本文繼續(xù)介紹計算機系統(tǒng)對時間的處理策略,并分類介紹時間處理的謬誤與陷阱注意:《編程復雜性》系列只算是半成品受筆者見識所限,文中提及的內容可能遠不及時間編程的復雜之萬一,歸類也可能并不準確,很多陷阱都是盤根錯節(jié),難以理清。

2.時間復雜度o(1)是什么意思

武漢城中村效的時間表示無效時間表示指給定的時間表示形式無法正確定位所指向的時間,通常由于該時間超出了表示形式所支持的時間范圍,或時間表示形式具有歧義性背景:計算機系統(tǒng)時間表示在計算機系統(tǒng)內表示時間通常有兩種形式:單值(絕對時間, absolute time)和多值(民用時間, civil time)。

3.時間復雜度o(1)和o(2)

單值時間的通常表示形式為:基于某個時間錨點,該時間距離錨點的時間差例如:Unix Time 是當前時間距離 1970/1/1T00:00:00Z UTC 時間為錨點的時間差,通常為秒數(shù)或更細粒度的時間單位。

4.時間復雜度o(1)的例子

NTP Time format 時間戳是當武漢城中村前時間距離 1900/1/1T00:00:00Z UTC 時間錨點的時間差NTP 的時間戳有 8 字節(jié)前 4 字節(jié)是作為無符號整型,表示秒數(shù);后 4 字節(jié)表示次秒粒度。

5.時間復雜度o(n)定義

多值時間的表示通常將“年/月/日/時/分/秒/… ”作為一個時刻的子組件例如 Python 的 datetimes 是使用以下的八元組表示:(year, month, day, hour, minute, second, microsecond, [optional] tzinfo)。

6.時間復雜度為o(n!)

忽略閏秒后,Unix 時間與標準日有著精確的對應關系因此,Unix 時間與 UTC 時間形成了武漢城中村一一映射關系同樣,一旦時區(qū)信息描述了與 UTC 的精確時差,本地時間與 UTC 可以形成一一映射關系因此,假設以下條件滿足,絕對時間與民用時間是等價(即可以相互轉換)的:。

7.時間復雜度為o(nlogn)的算法

絕對時間忽略閏秒民用時間包含時區(qū)信息,且以與 UTC 時差形式存在時間表示的局限通常有兩類:歷法局限性:所使用的歷法只支持有限時間區(qū)間例如,格里高里歷從 1582 年開始定義,無法嚴格表示 1582 年之前的時間。

8.時間復雜度o(n1/2)

實現(xiàn)局限性:指時間庫的實現(xiàn)導致的人為局限例如,Python 的時間庫只支持 0001-9999 年實現(xiàn)局限性實現(xiàn)的局限性的出現(xiàn)是由于追求實現(xiàn)的低復雜武漢城中村度,而放棄對少見場景或復雜情況的支持時間庫的取舍在當時可能是合理的,但是隨著時間(!)的推進,可能原來合理的設計會帶來新的問題。

9.時間復雜度o(n2)表明算法

典型的問題有數(shù)值溢出、超出區(qū)間和精度不足數(shù)值溢出Year 2000/Y2Khttps://en.wikipedia.org/wiki/Year_2000_problem最著名的千年蟲問題在上古時期計算機資源還非常昂貴的時候,一位數(shù)字的增減都可能會造成可觀的影響。

10.時間復雜度o(e)和o(1)區(qū)別

為了節(jié)省資源,有相當?shù)碾娔X系統(tǒng)從 COBOL 年代使用 YYMMDD 六位數(shù)字表示日期顯然,2000 年無法被正常地識別當時預估 Y2K 可武漢城中村能會造成最高 6000 億美元的經(jīng)濟損失不過,這個問題雖然很著名,其實際上造成的影響并不像當時媒體宣傳得那么嚴重。

當然,有可能得益于媒體關注,使得政府和公司等都在 2000 年到來前花費了大量精力修復相關問題,避免了最壞情況的發(fā)生當時有不少人認為這是一種病毒(甚至有人以為這是一種真正的病毒),以為末日即將來臨,甚至開始囤水囤食物。

例如在香港,有不少騙徒宣稱有千年蟲蛀蟲藥,誘騙對千年蟲問題一知半解的民眾購買,是當時典型的街頭騙案Year 2022微軟 Exchange 服務器出現(xiàn) 2022 年日期 Bug,暫時無法處理郵件,目前處理情況如何?- 知乎

2022 年的開年大事故微軟的 Exchang武漢城中村e 服務器出現(xiàn)問題,無法處理郵件事故原因很簡單,Exchange 使用 YYMMDDHHMMSS 的整數(shù)格式存儲,導致在 2022 年新年時超過了 int32 最大值 2147483648,導致溢出。

Exchange 當時緊急使用了 211233000001 這種格式來表示 2022/1/2,續(xù)了一命后續(xù)修復了這個問題這是一個典型的風險后置的例子 —— 好好的跑著的代碼改它干嘛?出事了再說Year 2036。

前文提及, NTP Time Format 使用 32 bit unsigned int 來表示從 1900/01/01 開始的秒數(shù)大部分人在使用時間戳時往往沒有感受,但其實一年有很多秒,武漢城中村2^31 秒只能表示大約 68 年的時間區(qū)間。

seconds_per_year = 365 * 86400 = 31536000presentable_years = 2147483648 / seconds_per_year = 68由于 NTP 無符號整型,所以它可以表示大約 68 * 2 = 136 年的時間區(qū)間。

NTP 是從 1900/01/01 作為錨定時間,所以它在 2036 年就會轉期,重新從 0 開始計數(shù)離現(xiàn)在還有 14 年,這是下一個千年蟲預祝所有的系統(tǒng)都可以正確地處理 NTP 的轉期這個問題相對不嚴重,因為 NTP 時間表示通常只在操作系統(tǒng)層面處理,不會透傳到軟件層面——也武漢城中村就是 NTP 時間表示通常不會用來作為時間的儲存格式。

所以只要操作系統(tǒng)及時更新即可另外,NTP Date Format 是更新的 NTP 格式,已經(jīng)轉換為了 128 bit int 來表示時間,使用 64 bit 表示秒這在宇宙完結之前應該不會溢出了Year 2038

前文提及,2^31 秒只能覆蓋約 68 年的時間而 Unix Time 默認是用 signed 32 bit int 來表示秒數(shù),所以只能表示約 68 年的時間Unix Time 是將 1970/01/01 作為錨點,所以它將會在 2038 年溢出。

Y2038 是一個堪比 Y2K 的嚴重問題當前大部分操作系統(tǒng)和比較知名的庫都做了適武漢城中村配并且進行了更新但是可以預見,到時一定會有一些老的系統(tǒng)會雞飛狗跳,并且再發(fā)生一串事故超出區(qū)間Year 1970無法使用 Unix time 表示任何 1970-01-01 之前的數(shù)字。

負值的 Unix time 是未定義的因此,不要使用 Unix time 表示所有可能早于 1970 年的時間例如,不要使用 Unix time 存儲的生日說起來您可能不信,但是這個世界上有人是早于 1970 年出生的。

Year 9999Python 時間庫使用民用時存儲時間它的年份的范圍是 datetime.MINYEAR (Year 1) 至 datetime.MAXYEAR (Year 9999)使用 Py武漢城中村thon 時間庫存儲超過公元 9999 年會有問題。

在天文學等領域,已經(jīng)開始造成困惑精度不足歷史上,CPU 的時鐘頻率很低,無法提供高精度的時間因此,有著久遠歷史的計算機系統(tǒng)在涉及時間時,往往會將其設計為較低的精度但現(xiàn)在隨著 CPU 時鐘頻率的提高,以及計算機應用對更高的精度的要求,這使得這些系統(tǒng)可能會造成精度損失。

當前,隨著 CPU 時鐘頻率的提升,大部分新的時間提供函數(shù)可以返回 ns 的精度但是要注意,這并不意味著這些函數(shù)的準確度是 ns 級別注意這兩者的區(qū)別是:精度是測量值之間的差值準確度是測量值與真實值之間的誤差。

首先,即使時間函數(shù)返回值的精度是 ns 級別,也不能說明所有的返回值的精武漢城中村度(即時鐘精度)實際上是 ns 級別時鐘的真實精度取決于操作系統(tǒng)和硬件實現(xiàn)其次,前文提到過,由于時鐘漂移,所以系統(tǒng)時鐘與真實時間一定會產生相對的偏差。

偏差值比實際精度的規(guī)模會大得多例如,如果 ntpd 每天同步時間,極可能會有 0.1 秒的偏差時間函數(shù)精度 <= 時鐘精度 <<= 時鐘偏差過度簡化的時間表示主要指在時間表示時忽略必要的信息所導致的問題。

民用時間不記錄時區(qū)如果不涉及國際化業(yè)務,一般會為了簡單起見,使用民用時間存儲時間戳時,不存儲對應時區(qū),而依賴系統(tǒng)自帶時區(qū)(通常是所在地時區(qū))這樣做的主要問題是,并沒有公認“正確”的本地時區(qū) -- 到底應該使用某個固定的時區(qū)(如東八區(qū)),還是 UT武漢城中村C,還是使用數(shù)據(jù)中心所在的時區(qū)?。

在國內,8 小時是一個神奇的常數(shù)一旦發(fā)現(xiàn)記錄的時間和預期相差 8 個小時,往往是因為某些地方設置了時區(qū)而某些地方未設置時間一個可行(但不完備)的檢驗是在單元測試中修改你的系統(tǒng)時區(qū),檢查測試是否仍然通過系統(tǒng)時區(qū)通過 TZ 環(huán)境變量定義。

例如在 Bazel 中,默認時間是 UTC可以通過設置 --test_env=TZ=Asia/Shanghai 調整時間為中國標準時間(CST)如果添加 --test_env=TZ=Asia/Shanghai。

與否會影響測試是否通過,那么代碼中存在潛在的風險變更系統(tǒng)時區(qū)也是高危操作這可能會導致非常隱蔽的問題發(fā)生考慮以下案例:CTO武漢城中村 們上任最喜歡干的一件事就是歸零化,即統(tǒng)一所有機房的時區(qū)到 UTC這確實是個基本無害的優(yōu)化 —— 唯一的缺點是確實可能有害。

假設我們有一個 CRON job,定期轉賬5 2 * * 1-5 # "At 02:05 on every day-of-week from Monday through Friday."注意 CRON 使用的是 $TZ 環(huán)境變量給出的系統(tǒng)時區(qū)。

本來是 UTC+8,轉換為 UTC,相當于時鐘回調 8 個小時那么,如果在今天已經(jīng)轉過一次賬,回調 8 個小時后,CRON 可能會在這一天再次觸發(fā)轉賬某些系統(tǒng)提供了 CRON_TZ 作為 CRON job 的時區(qū)。

顯式地聲明 Cr武漢城中村on 的時區(qū)有利于減少無意識更改時區(qū)而導致 Cron 錯誤觸發(fā)的問題以下是幾個導致事故的例子:https://blog.davidojeda.dev/4-time-zone-bugs-i-ran-into#the-bug-wrong-database-time-zone

建議升級 clickhouse-go 驅動 · gohangout · GitHubGo MySql driver doesnt set time correctly - Stack Overflow時間戳缺少單位

指使用數(shù)值 timestamp 表示一個時刻但是,該 timestamp 并沒有標明單位這使用戶很難猜測到底是什么單武漢城中村位把 timestamp 按錯誤的單位理解會導致各種問題發(fā)生時間運算本章討論對時間進行運算的易錯點。

中文里,“時間”具有多義性,可以表示:Time,即時間這個抽象概念Instant,即時間點,或時刻在英文中,Time 通常也會用以表示 Instant,如 what time is it?Duration,即時間量,或時長。

當討論“時間”,需要明確到底是時間點還是時間量非平凡的時間運算通常有兩種:Instant + Duration = Instant,即給定一個時間點,和一個時間偏移量,計算經(jīng)過偏移后的時間點Instant - Instant = Duration。

,即計算兩個時間之間的時間量武漢城中村差值(Duration +/- Duration = Duration 是平凡運算,這里不贅述Instant + Instant 是不良定義的)前文提及了兩種時間表示:絕對時間和民用時間,并且提及兩者在絕大多數(shù)情況下可以互相轉化。

所以,時間點用絕對時間還是用民用時間表示,通常并沒有影響運算的復雜之處在于時間量(Duration)前文介紹過,由于以下原因,絕對時間和民用時間的時間量并沒有穩(wěn)定的對應關系:一年有 365 天(閏年)一月有 30 天。

(每個月的天數(shù)都不盡相同)一天有 24 小時(夏令時)一小時有 60 分鐘(夏令時)一分鐘有 60 秒(閏秒)例如,當我們說“一個月后”,我們可能是指:武漢城中村30 天(30 * 86400 秒)后下個月同一日的同一時刻:由于上述的各種原因,“下一月同一日的同一時刻”有非常非常多的可能性。

為了方便起見, 本文沿用 Joda Time 的術語 Duration/Period 來區(qū)分兩個概念:Duration 是實耗時間/運行時間的絕對時間的長度Duration 的時間是絕對的,并且不受起始/終止時間影響。

Duration 可以通過秒、標準時、標準日等具有絕對時長定義的單位表示例如,一小時指一標準時,即 3600 秒一天指一標準日,即 86400 秒Period 作為運行時間考慮到歷法系統(tǒng)的民用時長度Period 的表示可以是自然天/年,因此 Perio武漢城中村d 的實耗時間(即 Duration)受起始時間的影響。

例如,2022.3.1 開始的一自然年與 2023.3.1 開始的一自然年時長不同,后者由于閏年,多一自然天在日常開發(fā)中,算術操作導致的問題主要分為兩類:混淆 Duration 與 Period運算結果不是有效時間,或者具有歧義。

以下以幾個常見場景的例子說明可能出現(xiàn)的問題計算 X min 后的時間考慮以下計算:Instant + Duration只不過 Instant 是用 DateTime 表示的, Duration 是以 n Hours m Minutes 表示的。

具體怎么做?看上去是一個很簡單——進位就是例如:2003:09:12:武漢城中村12:57:23 + 2:58 從秒開始進位 (23 + 58 >= 60),如果溢出繼續(xù)向上進位 (57 + 2 + 1 >= 60)。

這樣做會出現(xiàn)問題容易犯錯,尤其是進位可能會一直上升到年例如,在進位月份時,知道該天是不是當月的最后一天還涉及到閏年前后需要處理的邊界情況非常多更嚴重的問題是:沒有考慮時區(qū)變化,計算出來的結果可能是錯誤的。

這里將 Duration 錯當成了 Period考慮以下情況:# Pacific Time2022-03-13T01:00:00Z + 10800S = ?如果按前文的計算方式,會得到錯誤的結果:2022-03-13T04:00:00Z。

但是在 2022-0武漢城中村3-13 凌晨兩點時,夏令時開始,時鐘前調了一個小時所以,3 小時的 Duration 實際上相差了 4 小時的 Period計算兩個日期之間有幾天一個常見的任務是給定兩個日期,計算它們相隔相差多少自然天。

考慮下列的常見處理:time_t then_start_of_day = then_day.time()...; // 過去一天的零點,以秒為單位,本地時間time_t today_start_of_day = today.time()...; // 今天的零點,以秒為單位,本地時間constexpr kSecondsPerDay = 24 * 60 * 60; // 除以標準日時長days武漢城中村_between = (today_start_of_day - then_start_of_day) / kSecondsPerDay;

這可能會出錯,因為把 Period 誤作為 Duration:如果 [then, today] 的某一天因為 夏令時,只有小于 24 小時的民用時,那么這一天實際上會小于 kSecondsPerDay也就是說,上述的算法由于下取整,會比實際的天數(shù) 。

少一天更好的辦法是區(qū)分時間與日期,調用時間庫計算 then_day 與 today 日期之間相差的自然日定時任務周期性事件是業(yè)務開發(fā)中非常容易遇到的場景而且在大部分場景下,“周期”都是指民用時間周期,即 Peri武漢城中村od。

通常的例子包括:定期扣費、信用卡還單過生日注意到定時任務會涉及到前述的問題——算術結果不存在例如:閏年:1992.2.29 出生的人在 2022.2.29 的生日并不存在一月所含天數(shù)不確定:一個定期在每月 31 號扣費的服務,一年有 5 個月不存在 31 天。

對于不存在的時間,有幾種處理方式?jīng)]有絕對的正確與否,需要按照業(yè)務的實際情況判斷跳過適用于對發(fā)生的時間敏感,但對是否發(fā)生不敏感的情況例如,往往在 2.29 出生的人每四年過一次生日跳至最近的有效時間適用于對“必須發(fā)生”敏感,但對于發(fā)生的具體時間點并不敏感。

例如,按每月 31 號扣費時,每次 31 號并不存在時回退到當月最后存在的一天等武漢城中村價于按“每月最后一天”扣費報錯或者禁止可能導致無效的時間設定謹慎使用,對用戶造成影響較大當然,還有一個方案是不使用 Period 而使用絕對時間。

月卡,是常見的“一月后的今天”,例如充值續(xù)費等應該如何定義這一個月呢?Period/一個自然月:(MM, DD) -> (MM +1, DD or L)其中,L 是當月的最后一天,如果 DD > MM+1 月的天數(shù)。

Duration/“30 天” :續(xù)費固定為 30 天使用 Duration 有很多好處:計算簡單無需進行復雜的時間轉換,直接向時間戳添加 720 小時即可降本增效注意到假設用戶在一年的每一天都等概率地按月續(xù)費會員,那么,我們粗略地估計一武漢城中村年有約 365 天,如果只提供按 30 天續(xù)費,大約可提升 (365 - 360)/365 = 1/73 的運營收入。

(注:玩笑)按天聚合數(shù)據(jù)下面的例子是 (Instant - Instant = Period) 的隱蔽問題舉個例子,考慮一個服務器在硅谷的業(yè)務,需要按天聚合業(yè)務數(shù)據(jù)并進行數(shù)據(jù)分析一個自然的做法是:(簡化實現(xiàn),不考慮效率等因素)。

val init_date = Date(2015, 3, 24, "US/Mountain View")for i in 0 until 100 { val today = init_date.addDays(i)

val tomorrow = init武漢城中村_date.addDays(i + 1) val daily_events = events_between(today.toMicros(), tomorrow.toMicros())

// daily_events 是每一天的事件}這個做法看上去很自然,也很合理,好像也沒有上文所說的樸素運算導致的問題那么,這樣會有什么風險呢?答案是:會出現(xiàn)數(shù)據(jù)偏移由于我們通常使用的時區(qū)是基于地區(qū),tzdata 會自動切換夏令時。

因此,在一年中切換至夏令時和切換至常規(guī)時間的兩天,它們的一天分別有 23 小時和 25 小時,所以它們雖然確實是“一天(一自然日)”的數(shù)據(jù),但這一天可能會比正常日長或短,可能會導致數(shù)武漢城中村據(jù)異常這時,如果使用 Duration,反而不會產生時長的偏移。

但這樣會產生另一個問題:一年會有大概一半的時間的聚合不再是從[00:00, 24:00) 算做一天,而會是 [1:00, 1:00)這樣可能會導致其它的數(shù)據(jù)偏移發(fā)生另外,即使如此,在夏令時切換的那兩天,數(shù)據(jù)仍然可能會產生偏差——因此一天是 。

[0:00, 25:00),而另一天是 [1:00, 24:00),仍然可能產生數(shù)據(jù)的偏移當聚合遇上夏令時,沒有完美的方案理解業(yè)務模型,進而選取更符合業(yè)務的取樣法重復的時間(反方向的鐘)前文提及,夏令時可能會導致運算的結果不存在。

但是,更嚴重的問題是夏令時導致的時間回調,也就是同一個本地時間會武漢城中村發(fā)生兩次考慮如下時間,轉換成絕對時間是多少?date = "2022-11-06T01:30:00Z" Pacific Time答案是:不確定——因為夏令時結束在該天的凌晨兩點發(fā)生,這時時鐘會回調一個小時。

所以,凌晨一點到兩點的時間,都會發(fā)生兩次考慮這個場景:約定在這個時間向用戶轉賬 5000 萬錯誤的處理會導致轉賬兩次這將導致非常嚴重的事故對于具有二義性的時間,有幾種處理方式?jīng)]有絕對的正確與否,需要按照業(yè)務的實際情況判斷:。

觸發(fā)兩次,即在所有可能的時間解釋下都觸發(fā)適用于對發(fā)生的時間敏感,但對是否重復發(fā)生不敏感的情況例如鬧鐘觸發(fā)一次,選取回調前發(fā)生或者回調后發(fā)生適用于對于發(fā)生次數(shù)敏感的情況例如武漢城中村定時支付具體選取哪次,應該視業(yè)務場景而定。

報錯或者禁止可能導致無效的時間設定。謹慎使用,這將對用戶造成較大影響。下篇繼續(xù)介紹實際時間編程時容易犯的錯誤。

標簽列表