亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

蟲蟲首頁| 資源下載| 資源專輯| 精品軟件
登錄| 注冊

您現(xiàn)在的位置是:首頁 > 技術(shù)閱讀 >  【線上問題】P1級公司故障,年終獎不保

【線上問題】P1級公司故障,年終獎不保

時間:2024-02-10

前段時間,某個同事找我傾訴,說是因為strict weak ordering導(dǎo)致程序coredump,給公司造成數(shù)百萬損失,最終評級故障為P0級,年終獎都有點不保了,聽完不禁一陣唏噓。

之前的文章中,我們分析了std::sort的源碼實現(xiàn),在數(shù)據(jù)量大時候,采用快排,分段遞歸排序。一旦分段后的數(shù)據(jù)量小于某個閾值,為了避免快排的遞歸調(diào)用引起的額外開銷,此時就采用插入排序。如果遞歸層次過深,還會采用堆排序

今天,借助本文,我們分析下這次故障的原因,避免后面的開發(fā)過程中出現(xiàn)類似的問題。

背景

流量經(jīng)過召回、過濾等一系列操作后,得到最終的廣告候選集,需要根據(jù)相應(yīng)的策略,進行排序,最終返回首位最優(yōu)廣告。

struct AdItem {
  std::string ad_id;
  int priority;
  int score;
};

現(xiàn)在有一個AdItem類型的verctor,要求對其排序,排序規(guī)則如下:

  • 按照priority升序排列

  • 如果priority一樣大,則按照score降序排列

需求還是比較簡單吧,當(dāng)時線上代碼如下:

void AdSort(std::vector<AdItem> &ad_items) {
 std::sort(ad_items.begin(), ad_items.end(), [](const AdItem &item1, const AdItem &item2) {
   if (item1.priority < item2.priority) {
      return true;
    } else if (item1.priority > item2.priority) {
      return false;
    }

    return item1.score >= item2.score;
 } );
}

測試環(huán)境構(gòu)造測試case,符合預(yù)期,上線。

恐怖的事情來了,上線不久后,程序直接coredump,然后自動重啟,接著有coredump,當(dāng)時心情是這樣的。

定位

第一件事,登錄線上服務(wù)器,通過gdb查看堆棧信息

由于線上是release版的,看不了堆棧信息,將其編譯成debug版,在某臺線上進行灰度,不出意料,仍然崩潰,查看堆棧信息。

通過堆棧信息,這塊的崩潰恰好是在AdSort函數(shù)執(zhí)行完,析構(gòu)std::vector的時候發(fā)生,看來就是因為此次上線導(dǎo)致,于是代碼回滾,重新分析原因。

原因

為了盡快定位原因,將這塊代碼和線上的vector值獲取出來,在本地構(gòu)建一個小范圍測試,基本代碼如下:

void AdSort(std::vector<AdItem> &ad_items) {
std::sort(ad_items.begin(), ad_items.end(), [](const AdItem &item1, const AdItem &item2) {
  if (item1.priority < item2.priority) {
      return true;
    } else if (item1.priority > item2.priority) {
      return false;
    }

    return item1.score >= item2.score;
} );
}

int main() {
  std::vector<AdItem> v;
  /*
  給v進行賦值操作
  */


  AdSort(v);

  return 0;
}

執(zhí)行下面命令進行編譯,并運行:

g++ -g test.cc -o test
./test

運行報錯,如下:

通過gdb查看堆棧信息

線上問題復(fù)現(xiàn),基本能夠確認coredump原因就是因為AdSort導(dǎo)致,但是在AdSort中,就一個簡單的排序,sort不可能出現(xiàn)崩潰,唯一的原因,就是lambda函數(shù)實現(xiàn)有問題。

利用逐步定位排除法,重新修改lambda函數(shù),執(zhí)行,運行正常。

void AdSort(std::vector<AdItem> &ad_items) {
 std::sort(ad_items.begin(), ad_items.end(), [](const AdItem &item1, const AdItem &item2) {
   if (item1.priority < item2.priority) {
      return true;
    } else if (item1.priority > item2.priority) {
      return false;
    }
    
    if (item1.score > item2.score) {
      return true;
    }

    return false;
 } );
}

運行正常,那么就是因為lambda比較函數(shù)有問題,那么為什么這樣就沒問題了呢?

想起之前在<Effective STL>中看到一句話第21條:總是讓比較函數(shù)在等值情況下返回false。應(yīng)該就是沒有遵循這個原則,才導(dǎo)致的coredump。

那么為什么要遵循這個原則呢?打開Google,輸入std::sort coredump,看到了一句話

?

Having a non-circular relationship is called non-transitivity for the < operator. It’s not too hard to realise that if your relationships are circular then you won’t be getting reasonable results. In fact there is a very strict set of rules that a data type and its comparators must abide by in order to get correct results from C++ STL algorithms, that is 「strict weak ordering」.

?

從上面的意思看,在STL中,對于sort函數(shù)中的排序算法,需要遵循嚴(yán)格弱序(strict weak ordering)的原則。

嚴(yán)格弱序

什么是嚴(yán)格弱序呢?摘抄下來自wikipedia的定義:

?

A 「strict weak ordering」 is a binary relation < on a set S that is a strict partial order (a transitive relation that is irreflexive, or equivalently,[5] that is asymmetric) in which the relation "neither a < b nor b < a" is transitive.[1] Therefore, a strict weak ordering has the following properties:

  • For all x in S, it is not the case that x < x (irreflexivity).
  • For all x, y in S, if x < y then it is not the case that y < x (asymmetry).
  • For all x, y, z in S, if x < y and y < z then x < z (transitivity).
  • For all x, y, z in S, if x is incomparable with y (neither x < y nor y < x hold), and y is incomparable with z, then x is incomparable with z (transitivity of incomparability).
?

上面概念,總結(jié)下就是,存在兩個變量x和y:

  • x > y 等同于  y < x
  • x == y 等同于 !(x < y) && !(x > y)

要想嚴(yán)格弱序,就需要遵循如下規(guī)則:

  • 對于所有的x:x < x永遠不能為true,每個變量值必須等于其本身
  • 如果x < y,那么y < x就不能為true
  • 如果x < y 并且y < z,那么x < z,也就是說有序性必須可傳遞性
  • 如果x == y并且y == z,那么x == z,也就是說值相同也必須具有可傳遞性

那么,為什么不遵循嚴(yán)格弱序的規(guī)則,就會導(dǎo)致coredump呢?

?

對于std::sort(),當(dāng)容器里面元素的個數(shù)大于_S_threshold的枚舉常量值時,會使用快速排序,在STL中這個值的默認值是16

?

我們先看下sort的函數(shù)調(diào)用鏈(去掉了不會導(dǎo)致coredump的部分):

sort
-> __introsort_loop
--> __unguarded_partition

我們看下__unguarded_partition函數(shù)的定義:

template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
     _RandomAccessIterator
     __unguarded_partition(_RandomAccessIterator __first,
               _RandomAccessIterator __last,
               _Tp __pivot, _Compare __comp)
     {
       while (true)
     {
       while (__comp(*__first, __pivot))
         ++__first;
       --__last;
       while (__comp(__pivot, *__last))
         --__last;
       if (!(__first < __last))
         return __first;
       std::iter_swap(__first, __last);
       ++__first;
     }
     }

在上面代碼中,有下面一段:

while (__comp(*__first, __pivot))
         ++__first;

其中,__first為迭代器,__pivot為中間值,__comp為傳入的比較函數(shù)。

如果傳入的vector中,后面的元素完全相等,那么__comp比較函數(shù)一直是true,那么后面++__first,最終就會使得迭代器失效,從而導(dǎo)致coredump。

好了,截止到此,此次線上故障原因分析完畢。

此次故障,由于牽扯到算法、工程等部門,由于一開始的時候,不確定問題出在哪(一方面線上是release版本,一方面涉及到多個模塊的改動),幾個部門聯(lián)合分析,最終才定位到bug原因,期間曲折過程略去不表。

結(jié)語

這個故障,說真的,無話可說,只能怪自己學(xué)藝不精,心服口服,也算是給自己一個教訓(xùn),后面test case盡可能跟線上一致,把問題盡早暴露在測試階段。

這次把這個故障原因分享出來,希望大家在后面的開發(fā)過程中,能夠避免遇到同樣的問題。

好了,本期的文章就到這,我們下期見。


往期推薦



想拉著大家搞點事!

咳咳,說下開源項目這件事的進展

防御性編程技巧

C++的全鏈路追蹤方案,稍微有點高端

多線程程序中操作的原子性

C++反射TS初探

喵哥吐血整理:軟件開發(fā)的51條建議

為什么公司寧可高薪招一個新員工,也不愿意給老員工漲一點工資?

函數(shù)返回值的行業(yè)潛規(guī)則

面試常問的16個C語言問題,你能答上來幾個?

模版定義一定要寫在頭文件中嗎?


亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久偷看各类wc女厕嘘嘘偷窃| 久久久精品一品道一区| 欧美一区二区三区四区在线观看地址| 伊人精品成人久久综合软件| 国产欧美精品一区| 国产一区二区中文| 国产精品色婷婷| 欧美四级在线| 欧美午夜电影完整版| 奶水喷射视频一区| 免费成人av| 亚洲视频一起| 开心色5月久久精品| 六十路精品视频| 久久在线免费| 国产精品一区久久久久| 国产亚洲一级| 亚洲第一福利视频| 日韩一区二区福利| 亚洲综合大片69999| 国产一区二三区| 狠狠爱成人网| 亚洲激情影院| 一区二区三区日韩欧美精品| 亚洲性线免费观看视频成熟| 亚洲直播在线一区| 国产亚洲永久域名| 国内欧美视频一区二区| 伊人成年综合电影网| 亚洲欧洲日产国码二区| 99xxxx成人网| 午夜激情久久久| 久久久久国色av免费观看性色| 久久夜色精品国产欧美乱| 欧美激情91| 国产女优一区| 亚洲高清色综合| 一区二区三区欧美日韩| 亚洲欧美日韩一区| 免费观看一级特黄欧美大片| 欧美日韩国产一级片| 国产精品日本一区二区| 国内激情久久| 一区二区三区精密机械公司| 一区二区三区日韩在线观看 | 亚洲精品一区二区网址| 亚洲精品一区二区三区福利| 亚洲裸体在线观看| 欧美一区二区成人| 男人天堂欧美日韩| 国产精品免费看久久久香蕉| 在线看无码的免费网站| 亚洲一区在线观看视频| 模特精品裸拍一区| 国产欧美在线观看一区| 999在线观看精品免费不卡网站| 亚洲欧美日韩精品久久久| 欧美国产精品久久| 欧美视频官网| 在线日韩中文| 欧美一区二区成人| 欧美日韩免费一区| 亚洲国产精品久久91精品| 香蕉久久夜色精品国产| 欧美日韩午夜在线| 91久久黄色| 亚洲美女在线看| 久久久久久婷| 国产精品视频免费一区| 99re这里只有精品6| 免费短视频成人日韩| 欧美国产日韩免费| 一区三区视频| 一区二区久久| 欧美日韩一级黄| 亚洲欧洲精品一区二区三区| 欧美午夜精品电影| 最近看过的日韩成人| 久久久99爱| 韩国成人福利片在线播放| 亚洲国产中文字幕在线观看| 日韩亚洲欧美一区| 欧美激情一区二区三区高清视频| 国产婷婷成人久久av免费高清| 亚洲免费网址| 欧美精品一卡| 亚洲国产欧美日韩| 欧美xx69| 99国产一区二区三精品乱码| 欧美日韩国产一中文字不卡 | 激情婷婷亚洲| 欧美一区二区三区成人| 国产日韩欧美在线看| 亚洲免费影院| 亚洲免费观看高清在线观看 | 欧美日韩在线一二三| 欧美成人亚洲| 欧美不卡视频| 欧美激情在线观看| 欧美精品一区二区三区四区| 久久字幕精品一区| 男女精品视频| 欧美女主播在线| 欧美日韩精品免费观看视一区二区| 巨乳诱惑日韩免费av| 欧美一区二区三区免费视| 亚洲在线播放电影| 亚洲一区免费网站| 亚洲午夜久久久| 一本一本久久a久久精品综合麻豆| 极品中文字幕一区| 在线观看成人小视频| 国语自产偷拍精品视频偷| 激情综合电影网| 国产中文一区二区| 亚洲高清不卡av| 一区二区日韩伦理片| 香蕉成人伊视频在线观看| 久久国产精品电影| 牛人盗摄一区二区三区视频| 欧美久久一级| 国产精品色婷婷久久58| 国产一区美女| 亚洲日本aⅴ片在线观看香蕉| 亚洲蜜桃精久久久久久久| 亚洲欧美福利一区二区| 久久久久久久久岛国免费| 久久人人97超碰国产公开结果| 欧美福利小视频| 欧美先锋影音| 国产在线拍揄自揄视频不卡99| 韩国精品主播一区二区在线观看| 亚洲国产精品第一区二区| 亚洲美女在线看| 欧美一区二区私人影院日本| 美女精品国产| 国产精品一区免费观看| 影音先锋中文字幕一区| 制服丝袜激情欧洲亚洲| 久久精品欧美| 国产精品99免视看9| 影音先锋成人资源站| 亚洲欧美一区二区三区久久| 久久综合一区二区| 国产精品毛片大码女人 | 欧美在线视频全部完| 欧美成黄导航| 国产精品亚洲网站| 亚洲日本va午夜在线影院| 先锋影音久久| 欧美日韩1区2区| 国产午夜精品理论片a级大结局| 在线播放亚洲| 亚洲欧美一区二区原创| 久久久美女艺术照精彩视频福利播放 | 国产亚洲精品成人av久久ww| 好看的av在线不卡观看| 一本大道久久a久久精品综合| 久久精品盗摄| 国产精品久久福利| 伊人久久综合97精品| 亚洲在线视频观看| 裸体素人女欧美日韩| 欧美日韩综合| 亚洲承认在线| 欧美专区中文字幕| 国产精品自在欧美一区| 亚洲性xxxx| 欧美视频一区二区三区| 亚洲激情欧美激情| 久久亚洲精品一区二区| 国产精品综合不卡av| 亚洲你懂的在线视频| 欧美色综合网| 99精品欧美一区| 欧美欧美在线| 亚洲精品久久久一区二区三区| 蜜臀a∨国产成人精品| 狠狠操狠狠色综合网| 久久全国免费视频| 国产综合欧美| 久久综合给合久久狠狠狠97色69| 国产亚洲午夜高清国产拍精品| 先锋影音久久| 激情成人亚洲| 欧美第一黄色网| 亚洲精品无人区| 欧美日韩一区二区精品| 一区二区三区四区蜜桃| 欧美午夜无遮挡| 亚洲免费婷婷| 国内精品久久久久影院优| 久久亚洲精品一区二区| 亚洲欧洲综合另类在线| 欧美视频你懂的| 欧美资源在线| 亚洲乱码国产乱码精品精| 欧美日韩国产123区| 亚洲欧美大片| 亚洲国产精品久久久久婷婷老年|