主頁 > 後端開發 > 《作業碰上的技術問題及處理經驗》(五)

《作業碰上的技術問題及處理經驗》(五)

2020-09-16 12:05:26 後端開發

續上一篇隨筆:https://www.cnblogs.com/kingstarer/p/12249028.html《作業碰上的技術問題及處理經驗》(四)

 

我這人記憶力比較差,經常出現有些知識學了不久后就忘了,或者有些問題花了很多時間百度解決后,再過一段時間碰上時只有模糊印象,卻忘了具體解決方法,

最近幾年作業時我開始有意識地把登記每天作業碰上的技術問題做個簡單筆記,

一般上班時間比較忙,只能草草記了一兩句話,等過一段時間,我會把這個筆記整理一下,把問題和處理經驗整理通順,以加深自己的印象,

 

20190402:
    今天碰上一個腳本檔案編碼與系統編碼不符,導致sed運行報錯的問題,我腳本里面寫了一個命令sed -e 's/月份/月份 ${V_MONTH}/g'
執行時報錯"sed: -e expression #1, char 21: unterminated `s' command"
    我在執行sed之前先執行set -x,打開腳本除錯模式,看到輸出是sed -e "s/\324\302\267\335/\324\302\267\335 201904/g",
這個輸出說明編碼是GBK,因為一個中文占了兩個位元組,但我系統的LANG設定為en_US.UTF-8,不相符,所以需要改一下,

20190407:
    今天發現xargs命令做字串處理還是挺方便的,以前知道用它來跟管道組合處理引數太多超過命令列限制的情況,這里摘錄幾個用法:
替換字串:echo "nameXnameXnameXname" | xargs -dX
多行輸入單行輸出:(echo a; echo b; echo c) | xargs
組裝shell命令:cat arg.txt | xargs -I {} ./sk.sh -p {} 



20190408:
    今天發現sourceinsight雙擊選中文字后會自動被修改,變成一個奇怪的問號圖示,開始以為是我鍵盤有鍵被卡住了,挨個鍵檢查了一下,沒發現問題,
    后來偶然發現原來我打開了金山詞霸,想起以前也看過網友吐槽,詞霸里面的取詞和劃譯功能實作方法很粗暴,會不停往系統發快捷鍵訊息,
    于是嘗試把金山詞霸關了,果然好了,



20190409:
    今天發現oracle的systimestamp型別是帶時區的timestamp,需要用cast(systimestamp as timestamp)轉換一下才變成不帶時區的,

    今天用proc*c寫的程式匯出資料庫表資料,發現有一些欄位值是NULL,但我程式沒報錯,理論上proc如果不用指示變數,取出空的資料時會報錯的,
    后來查查,發現原來我這個程式用proc*c預編譯時設定了UNSAFE_NULL=yes,所以沒報錯,


20190410:
    今天發現oracle有一個語法insert all,可以指定一條記錄同時插到兩個庫表:
    insert all
        into t1(c1)
        int t2(c2)
    select * from t;
    
    proc*c執行dml陳述句時支持預編譯一次,執行sql多次,不過前提是要設定選項release_cursor=no(默認是no)

    今天發現proc有一個引數:prefetch,指定sql陳述句句柄打開后預先從資料庫取出多少條記錄,這個引數默認是1,批量任務可以考慮把它改大,有助于提高性能,


    今天想用gcc的-Og選項編譯程式,發現居然不支持,估計是我用的版本太低了,網上說-Og選項只會打開與-g不沖突的優化選項,

20190415:
    今天發現cp有一個引數-p,復制時保留原檔案的修改時間:cp -p old new
    shell清空檔案的技巧 true命令: true > emptyfile


20190416:
    用awk寫了一個輔助宏代碼對齊的腳本
    # 輸入宏代碼,腳本會在每行后面補齊空格和\
    awk -v v_tab_lenth=8 '{
    # 首先讀取所有輸入行 計算所有輸入文本單行最大長度
    v_arr_input[NR] = $0;
    v_str_len = length($0);
    v_arr_input_len[NR] = v_str_len;
    if (v_str_len > v_max_len) v_max_len = v_str_len;
}
END{
    v_max_tab_cnt = int(v_max_len / v_tab_lenth) + 2;
    print "v_max_tab_cnt = "v_max_tab_cnt
    for (i = 1; i <= NR; ++i)
    {
        v_str_tab_cnt = int(v_arr_input_len[i] / v_tab_lenth);
        v_tab_cnt = v_max_tab_cnt - v_str_tab_cnt - 1;
        #if (v_str_tab_cnt * v_tab_lenth < v_arr_input_len[i]) v_tab_cnt = v_max_tab_cnt - v_str_tab_cnt - 1;
        #else v_tab_cnt = v_max_tab_cnt - v_str_tab_cnt;
        
        # print "v_tab_cnt = "v_tab_cnt, "v_str_tab_cnt = "v_str_tab_cnt, "v_arr_input_len[i] = " v_arr_input_len[i]
        printf("%s", v_arr_input[i]);
        for (j = 0; j < v_tab_cnt; ++j)
            printf("\t");
        print("\\");    
    }
}' tmp.txt


20190417:
    今天發現一個函式fcloseall(_fcloseall),作用是把fopen打開的檔案句柄全關了,
但我實際測驗,發現fopen打開一個句柄fp,然后呼叫fcloseall,但這個fp句柄還可以正常讀寫和關閉,
    不過確實證明它有fflush的作用,


20190420:
    今天發現proc查詢資料到char *型別縮主變數,居然是通過strlen計算其空間大小,
這個設定好奇怪,在官方檔案里面也提醒了呼叫者,需要用非'\0'字符填充空間,
    
    proc執行rollback/commit會影響sqlca.sqlcode,所以如果需要這個值要先備份起來,


20190423:
    今天創建一個磁區表時發現oracle在創建表的速度比刪表的速度快很多,
創建陳述句雖然很長,但oracle一般在十幾毫秒內能完成,刪表陳述句很短,但執行要數秒鐘,
    暫時不知道是什么原因導致的,

20190424:
    今天復習了oracle的savepoint語法:
    savepoint a;
    rollback to a;

    今天我寫了一個函式,使用proc*c的陣列批量操作技巧,一次插入N條記錄,
    但是有一個問題沒解決,如果在插入程序中陣列里面某些元素由于資料例外插入失敗怎么處理?
    我暫時的解決方法是:插入前先使用savepoint建立一個保存點,如果插入失敗則回滾到該保存點,
    不知道plsql里面的forall命令是怎么實作的使用forall批量插入資料時,如果某個資料插入出錯會忽略,繼續執行,
所有出錯記錄會存在sql%bulk_exceptions陣列的,

20190428:
    今天同事分享的一個問題:進行非功能測驗,隨著時間增長,交易速度有明顯下降,
后來查了一下日志,發現有一些sql執行耗時例外,通過分析sql執行計劃,發現sql沒走索引,
再進一步分析原因,是因為庫表沒有及時做統計收集,oracle以為是空表,本來應該走索引的,給走了全表掃描,
    一般認為,庫表記錄較小(小于100)或者查詢的資料量超過總資料的10%走全表掃描比走索引掃描快,(一次順序IO比多次隨機IO快)


2190506:
    今天花了點時間查了一個proc的問題:
    執行update陳述句時沒找到記錄,sqlca.sqlcode回傳1403,但是前面我用EXEC SQL WHENEVER SQLERROR DO指定的proc錯誤處理函式沒有被呼叫,
    后來把.pc檔案翻譯成.c檔案看,才知道EXEC SQL WHENEVER SQLERROR DO指定的函式只有在sqlca.sqlcode < 0時才會被呼叫,

    今天還注意到一個oracle語法細節:select for update后面還可以跟上of 欄位,指定只鎖定記錄哪些欄位,
    select from hch for update of c1;


20190507:
    查看正在運行程式環境變數的方法: strings /proc/${PID}/environ

20190508:
    今天使用valgrind檢查程式記憶體使用情況,發現有幾個出錯位置函式堆疊里面沒有main,而且里面都是一些oracle底層的函式,后來發現原因是出錯位置函式呼叫層次太深,超過了默認值12, 我重新啟動valgrind,加上引數--num-callers=100,這樣就能顯示從main到出錯位置的所有函式,

20190509:
    今天看到了這樣的代碼:
    if (bFlag)
    {
        EXEC SQL CONTEXT USE :ctx;
    }
    else
    {
        EXEC SQL CONTEXT USE DEFAULT;
    }

    EXEC SQL ...;
    寫代碼人的本意根據bFlag的值決定使用不同資料庫連接執行sql,但這樣寫是有問題的,因為EXEC SQL CONTEXT并不是一個陳述句,
它有點類似C語言的宏定義,在預編譯后根本不存在,(把.pc檔案預編譯成.c后"EXEC SQL CONTEXT USE"這段代碼就是一段注釋)
    他這樣寫代碼問題就跟用C語言這樣寫代碼一樣:

    #define SQL_CONTEXT_USE  ctxDeault

    if (bFlag)
    {
        #undef SQL_CONTEXT_USE
        #define SQL_CONTEXT_USE ctx
    }
    else
    {
        #undef SQL_CONTEXT_USE
        #define SQL_CONTEXT_USE DEFAULT
    }
    
    EXEC_SQL(SQL_CONTEXT_USE); //無論bFlag的值是什么,這里都是用EXEC_SQL傳的值都是ctxDeault

    正確寫法應該是這樣:
    if (bFlag)
    {
        EXEC SQL CONTEXT USE :ctx;
        EXEC SQL ...;
    }
    else
    {
        EXEC SQL CONTEXT USE DEFAULT;
        EXEC SQL ...;
    }

201900512:
    今天一下網友分享一個案例:他用瀏覽器訪問某個網站時能正常獲取頁面資訊,但用爬蟲訪問時卻獲取不到,
他已經修改了http請求頭,把agent改成跟瀏覽器的一樣也不行,
    后來他發現原來是訪問網站時服務器會回傳一段js,瀏覽器執行那段js后才能正常生成頁面資訊,他的爬蟲不支持js決議,所以出了錯,

201900513:
    oracle應用程式,有時會需要使用sysdate(或者序列號)修改庫表欄位,但又想知道修改后的值是什么,這時可以使用returning into 子句,示例代碼如下:

    set lines 1000 pages 1000
    set serveroutput on
    alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
    alter session set nls_timestamp_format='yyyy-mm-dd hh24:mi:ss.FF6';
    alter session set nls_timestamp_tz_format='yyyy-mm-dd hh24:mi:ss.FF6 TZR';
    drop table tab_hch;
    create table tab_hch(c1 date, c2 timestamp);
    declare
        v_dt date;
        v_dtmicro timestamp;
    BEGIN
        insert into tab_hch(c1, c2) values(sysdate, systimestamp) returning c1, c2 into v_dt, v_dtmicro;
        dbms_output.put_line('c1 = ' || v_dt);
        dbms_output.put_line('c2 = ' || v_dtmicro); -- 這里輸出的時間就是新插入的記錄c2的值
    END;
    /
    col c1 for  a20
    col c2 for  a32
    col c3 for  a20
    col c4 for  a34
    -- 比較c2與dbms_output.put_line的值,看是否一致
    select c1, c2, sysdate c3, systimestamp c4 from tab_hch;




20190515:
    oracle 交換磁區如果存在全域索引,會導致全域索引失效,可以在交換磁區時加上with update global index

20190529:
    sqlplus系結變數用法:
    var v_hch number; 
    exec :v_hch := 1;
    print :v_hch;
    select :v_hch from dual;


20190530:
    今天碰上makefile里面執行cd失效導致遞回編譯的問題,事情是這樣的:有一個程式編譯時要求先到子目錄下面執行makefile編譯后,再回到當前目錄編譯,于是我寫了下面這個makefile,
prog:
    cd common
    make $@
    cd ..
    make $@
    結果編譯時發現make被無限回圈呼叫了,網上查了一下,要這樣寫cd common && make $@,原來每次執行一行命令后,makefile會重新回到當前作業目錄,所以我原來的makefile等于無限回圈呼叫make編譯,


    今天有網友問我他們系統有一個一個行程卡住,不知道是死回圈了還是在等待什么條件,要怎么辦,我建議他用pstack看一下堆疊,結合代碼分析程式的狀態,



20190531:
    寫了一個awk腳本,用于把長行拆成多個短行,里面考慮到了行尾單詞連續性問題:
    awk -v v_line_len=70 '{
        v_str = $0;
        v_TotalLen = length(v_str);
        

        while(1)
        {
                v_str_sub = substr(v_str, 1, v_line_len);
                nLen = length(v_str_sub);
                if (nLen < v_line_len)
                {
                        print v_str_sub;
                        break;
                }
                nLen = v_line_len;
                v_ch = substr(v_str_sub, nLen, 1);

                # 如果結尾不是非字母或者數字,則一直往前找,直到找到第一個非字母或者數字的字符
                # 如果找了20個還找不到,則放棄 這樣做是為了避免行尾的單詞被一分為二
                while ((v_ch == ":") || (v_ch >= "a" && v_ch <= "z") || (v_ch >= "A" && v_ch <= "Z") || (v_ch >= "0" && v_ch <= "9"))
                {
                        --nLen;
                        v_ch = substr(v_str_sub, nLen, 1);
                        if (nLen <= v_line_len - 20)
                        {
                                nLen = v_line_len;
                                break;
                        }
                }
                v_str_sub = substr(v_str, 1, nLen);
                print v_str_sub;
                v_str = substr(v_str, nLen + 1);
        }
    }'


20190603:
    今天學習了makefile一個特殊變數:MAKECMDGOALS 這個變數記錄了命令列引數指定的終極目標串列,
舉例:執行make debug命令,MAKECMDGOALS的值是debug,在遞回腳本里面這個引數很有用,
    make還有其它幾個特殊變數,分別代表當前目錄,makefile名稱,make版本等



20190604:
    今天碰到一個情況:df顯示磁盤空間還剩很多,但用cp命令拷貝生成新檔案時提示no space left on device,
上網查了一下,說可能是磁盤inodes空間滿了,用df -i可以查看,
    我試了一下,果然如此,用df可以看出inodes空間占用 100%,cd到懷疑有大量檔案的目錄下,ls時卡住了,無法定位是什么檔案導致的,
    沒辦法最后只能把目錄刪了重建,


20190605:
    oracle寫sql時如果需要指定轉義字符(k逃逸字符),可以使用escape關鍵字,例如:
select owner, table_name from all_tables where table_name like '%\_17_\_%' escape '\'; -- 找出所有以包含"_17?_"的表名,?代表一個任意字符


    fuser可以查看檔案被哪些行程打開

    ${0}:${LINENO} shell輸出日志加上這個前綴,可以更方便定位
    bash里面還可以使用${FUNCNAME[0]}輸出當前函式名稱

    一個日志輸出函式示例:
    logerr() {
    echo  "error at ${BASH_LINENO[1]}${FUNCNAME[1]} $*" 
}
20190613:
    由于oracle的索引是不記錄NUUL值記錄,所以唯一索引列是可以存在多個為NULL的記錄的
    另外,oracle的NULL和空串''是等價的

20190614:
    寫了一個方便查看檔案資料的awk腳本(讀取行,拆成多列顯示)
    awk -F '\\|@\\|' '{
        printf("%s:%d\n", FILENAME, FNR);
        for (i = 1; i <= NF; ++i)
        {
            printf("% 4d:%s\n", i, $i);
        }
        
        getline < "-";
    }'   


20190616:
    一個web請求可能需要經過的cdn,dns負載均衡,f5負載均衡,nginx反向代理,訊息佇列,redis,資料庫(讀寫分離,集群),檔案緩沖等這么多種快取機制



20190620:
    使用static變數時,記得注意變數之間關連關系,我這次就踩了坑:
我在程式里面使用了兩個static變數s_this_date快取當前時間,s_next_date快取s_this_date的下一天,
    為減少計算時間消耗,只有當s_this_date變化時,才會計算s_next_date,
    但代碼里面有個問題,存在修改了s_this_date后,在s_next_date修改前函式就退出的情況,
    這樣就導致s_next_date有時跟s_this_date不是差一天的關系,
    
20190630:
    select for update是上鎖,不是檢查有沒有鎖

20190701:
    今天使用了merge陳述句幫同事優化了一個陳述句:
    update tab_check_task t set Mcht_Name=(select Mcht_Name from tab_mcho_sre where mcht_no=t.mrch_id );
    13分鐘沒跑完
    merge into  tab_check_task t  using tab_mcho_sre  mcht on (mcht.mcht_no=t.mrch_id) when matched then update set t.Mcht_Name = mcht.Mcht_Name;
    4分鐘跑完

    今天一個同事說他在.bash_profile配置了兩個環境變數,但重新登錄后只有其中一個生效了,問我怎么回事,
我建議他執行sh -x .bash_profile,看是哪里出錯了,他執行后很快回復我,是.bash_profile后面加載了另一個腳本,那個腳本里面有同名變數,相互覆寫了,
    sh -x 是除錯shell的利器,‘


20190704:
    今天發現time命令和\time呼叫的是不同的程式,\time呼叫的是/usr/bin下面的time程式,而time則是呼叫shell內置的功能

    
    今天看到一個除錯一個release程式的方法:
    先使用-g重新編譯一次程式,然后取出變數資訊
    objcopy --only-keep-debug projedtd projedtsymbol.dbg
    再使用這些變數資訊去除錯release程式
    gdb -q symbol=projedtsymbol.dbg --exec=projectr

    x /10x $sp  # gdb查看當前程式堆疊的內容: 列印stack的前10個元素

20190705:
    除錯記憶體問題時,可以設定環境變數
    export MALLOC_CHECK_=3
    這樣程式在發現記憶體例外時會列印出錯資訊并退出


20190712:
    今天來上班,發現昨天晚上掛的一個crontab任務沒啟動,一開始沒想明白是什么原因,以為是任務腳本有問題,查半天沒查出來,
后來在同事建議下,我試了加了一個簡單的crontab任務,設定成1分鐘后跑,發現也沒啟動,這才確定原來是crontab服務沒啟動,可以使用以下命令確認:
    service crond status
    

20190715:
    proc呼叫存盤程序,出參,也要初始化,不然使用valgrind檢查時會提示未初始化的記憶體,

20190716:
    今天使用vallgrind檢測程式時,出現很多記憶體泄漏提示,
但其實我確認代碼沒寫錯,后來查了一下,是因為使用了glib的一些資料結構,里面使用了記憶體池,
并且查到了,如果設定環境變數G_SLICE=always-malloc這樣就不會啟動glib記憶體池,

20190717:
    今天看代碼時發現一段邏輯,需要判斷一張資料庫表有沒有記錄,里面直接用了select count(*) from tab檢查,其實可以使用
select count(*) from tab where rownum < 2,因為要檢查有沒有記錄,只要有一條記錄就可以判斷,不需要全表掃一次,

20190718:
    從csdn上保存的博文,在沒有連公網時打開,總是過一會就自動重定向到csdn.net,很煩人,雖然知道肯定是某段js搞鬼,但一直沒搞清楚是哪段,
今天發現用谷歌瀏覽器按f12可以單步除錯網頁,利用這功能終于定位到了“元兇”,
    <img src=https://www.cnblogs.com/kingstarer/p/"https://blog.csdn.net/chuxuan909/article/details/72465748?utm_source=blogxgwz0" 
onerror="setTimeout(function()
{if(!/(csdn.net|iteye.com|baiducontent.com|googleusercontent.com|360webcache.com|sogoucdn.com|bingj.com|baidu.com)$/.
test(window.location.hostname))
{window.location.href=&quot;\x68\x74\x74\x70\x73\x3a\x2f\x2f\x77\x77\x77\x2e\x63\x73\x64\x6e\x2e\x6e\x65\x74&quot;}},3000);
">
    把onerror批量替換成onerror1即可,這段代碼里"\x68\x74\x74\x70\x73\x3a\x2f\x2f\x77\x77\x77\x2e\x63\x73\x64\x6e\x2e\x6e\x65\x74"
其實就是https://www.csdn.net


20190719:
    kafka閱讀心得:
觀察臟頁
cat /proc/vmstat | egrep 'dirty|writeback'

啟動g1垃圾回收器

export KAFKA_JVM_PERFORMANCE_OPTS='-server -XX:+UseG1GC
-XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+DisableExplicitGC -Djava.awt.headless=true" 
kafka-server-start.sh -daemon server.propertities

20190724:
    proc對匿名結構體支持不大好,建議盡量使用typedef struct __StuName_t{}StuName_t;代替typedef struct {}StuName_t;


20190725:
    sqlldr加快裝載速度的引數設定建議:
    sqlldr errors=9999999 control=tab.ctl log=tmp.txt sreamsize=256000 bindsize=2560000 userid=stlm_o/stlm_o@RCC8TPD2 direct=TRUE rows=1000

20190726:
    今天發現有一些商家使用退貨交易套利:
    第一天先做了一大筆消費,第二天一開門就做了退貨交易,由于這時商戶資金不足,為了不影響用戶體驗,我們系統會先墊錢給用戶,后面再從商戶的賬戶扣錢,
    但有一些不法商戶跟消費者合作,退款后立即注銷商戶,導致系統出現短款,
    為了解決這個問題,我們緊急做了一個白名單功能,不在白名單的商戶,當日營業額不足時不允許退貨,(這種情況商家一定要退貨時,需要自己先做一筆大額消費)

20190731:
    今天過來發現crontab任務沒啟動(檢查crontab任務重定向輸出的日志,發現不存在),檢查一下,發現因為是硬碟沒空間了,這才知道原來硬碟滿了會導致crontab調度例外,


20190801:
    今天才發現df出來的size != used + free,查了一下,說原因有兩個1 inode節點空間占用了一些磁盤空間,2 系統會占用一些預留空間,以便出現磁盤空間滿時止root用戶登錄處理(一般是0.05 * size),不過我的系統加上這兩項空間,還是差一些,不知道是不是還有其它隱藏的占用空間情況,

20190810:
    這段時間都在研究kafka,kafka其實就是一個分布式訊息佇列中間件,主要用于吞吐量高(號稱每秒十萬寫,百萬讀),但業務邏輯簡單(如資料同步,通知)的場景,
    kafka借助zookeeper實作了集群,高可用特性,本身又支持多副本功能,集群少量機器出現故障時仍可正常使用,但kafka的訊息一致性比較差,容易出現訊息丟失或者重復訊息的情況,
    kafka支持多個不同客戶端訂閱同一個訊息主題,這樣可以做到一份訊息多個場景使用,這點對于資料分析特別有利,另外,kafak的訊息都是落盤存盤的,所以生產者跟消費者耦合非常低,可以分別獨立部署運行,


20190812:
    這幾天用glib寫了一個多執行緒的程式,鏈接時報g_thread_init函式未定義(undefined reference to `g_thread_init'),但奇怪的是我明明有libglib-2.0.a,原來網上查了一下,原來是要額外鏈接libgthread-2.0.a
    cout從右到左計算,從左到右輸出


    lsof  -u username # 列出用戶所有打開的檔案


20190814:
    今天編譯libcjson.a,發現默認的編譯選項是沒有開啟-O2的,不知道為什么,我把它改了一下,增加-O2選項,發現只快了一點,
跑10萬次cJSON_test,耗時從1.15s降到0.97,又測驗了5000000次的,發現分別耗時是55秒和45秒,還是有點效果的,但效果不明顯,先使用默認的吧,


    今天又出現某個bug增加列印日志 就不出現,不加就出現的情況,后來仔細看代碼,是因為我有兩個不同檔案,同時宣告了一個全域變數(名字一樣),其中一個有初始化,一個未初始化,導致兩個變數鏈接時被合并成一個,從而互相影響,
    


20190815:
    今天發生一個事情,由于溝通問題,我跟同事改了同一個word檔案,只能想辦法跟他的合并,網上找了一下,說word的審閱選項卡下面有比較功能,
    試了一下,確實是可以,但不是很直觀,后來經同事提醒,原來svn自帶啟動word比較功能,


20190820:
    今天發現ue有一個好用的快捷鍵F5,作用是把大寫資料庫列名轉成駝峰式的大小寫混合的單詞,例如THIS_IS_A_TEST會被變成This_Is_A_Test

20190821:
    小知識點:free命令輸出的記憶體使用資訊里面used并不代表真正可用記憶體,可用記憶體是free + buffer + cached之和

20190822:
    extern int g_lib_flag = 0; //鏈接時報錯 extern不能增加初始化

20190823:
    今天生產系統發現有一些交易存在沖正交易比正交易先到,導致對賬不平的情況,
    出現bug的主要原因是我們接到沖正請求時發現資料庫沒有正交易,直接就回傳前端沖正失敗(交易不存在),但沒有登記流水,后面正交易過來時我們當普通交易正常處理了,但前端系統不知道,所以沒有重復發起沖正請求,
    暫時要求前端嚴格控制順序發送交易,以后再出現需要考慮一些機制避免這種差異,

20190904:
    這兩天使用Loadrunner對程式進行壓測,壓測程序中經常提示壓力機cpu使用率超過80%的提示,開始時我沒怎么在意,想著不是目標機80%,壓力機沒到100%應該沒事,
    后來偶然把測驗腳本改一下,壓力機cpu消耗下來,發現目標機tps居然有明顯升高,
    看來以后要注意一下,

    oracle默認洗掉表后不會清除空間,而是放到回收站,如果要強制識訓這些空間,可以使用select * from user_recyclebin;查出表名,然后使用
    purge table "表名";


20190914:
    今天發現一個bug:
    我們一個程式在執行資料庫查詢程序中,收到信號,轉去執行中斷處理函式,
結果函式里面也有資料庫查詢操作,導致死鎖了,(proc的api對于這種情況沒處理好)
    臨時解決方法是在資料庫操作期間先屏蔽了信號,不過這樣可能導致信號漏處理,以后需要優化,

20191030:
    之前對日志組件做了優化,使用自己寫的帶快取的localTimeCache代替localTime,減少鎖競爭,
    今天寫了一個測驗,發現在高頻呼叫下時,有時會出現跟localTime的秒數有差異的情況,代碼如下:
    while (1) 
    {
        int *pSecCache = &localTimeCache(&time)->tm_sec;
        int *pSec = &localTime(&time)->tm_sec;
        LogInfo("cache %d", *pSecCache); 
        LogInfo(" nocache %d\n", *pSec);
    }
    后來仔細分析,原來LogInfo里面也會呼叫localTimeCache,導致pSecCache的值發生了變化,對于這種靜態變數使用,需要多注意,

    今天又碰上一個行程因為信號處理函式出bug的情況:在呼叫system函式時接到信號,轉到信號處理函式時又呼叫了system,導致死鎖,


20191030:
    proc查詢資料庫資料到char陣列時,如果目標陣列空間不足,則會截斷(但還是會以\0會結尾),
如果陣列空間比資料庫欄位長度長,則剩下的空間會以空格填充,



20191114:
    void func(char * const arr[])
    只讀字串陣列

    strcpy(arr[0], "123"); //ok
    arr[0] = "123"; // not ok

20191125:
    oracle 在線壓縮磁區的方法:
1 完美方法
使用12 c的move online功能

2 變通方法a
先將要壓縮的磁區資料匯出來到臨時表并壓縮
把臨時表的資料跟待壓縮磁區做在線交換(要加上with update indexes)
從臨時表里面找操作期間變更的記錄,更新回壓縮磁區


3 變通方法b(壓縮磁區不需要查詢的情況)
建一個空表
把磁區的資料跟空表交換
對表做壓縮


20191126:
    oracle做磁區交換時,可以使用including indexes,在做交換磁區時順便維護local索引

    float型別的變數在計算時很容易損失精度:0.1回圈加8次 > 0.8
    double也會,但比float損失精度的概率會低一些,

20191127:
    今天出現一個問題:我在程式里面一個sql使用了hint:result_cache想提高查詢速度,單行程測驗時發現確實有明顯改善,
但到生產機器時,多行程環境跑的時候卻導致了大量lanth free事件,反而拖慢了速度,后來dba臨時關閉了result_cache功能才恢復,


20191204:

行程數估計 機器cpu跑滿  看是否有堵塞

交易太頻繁,沒有發心跳 mq recv



20191205:
    oracle使用merge into有時也會因為主鍵沖突失敗,主要是出現在高并發插入的場景,


20191206:
    watch命令特別方便監測行程運行情況:執行
    watch 'ps aux www|grep -w -E "ProgName|TTY"'
    系統會顯示行程資源占用情況,并且自動每2秒重繪

20191207:
    今天使用valgrind檢測程式時,發現好多invalid write,仔細檢查,發現是因為
strptime函式沒有填充目標變數的夏令時欄位,導致這個欄位是未知位元組,然后我又拷貝了這個變數的值,就出現這個問題,
    解決方法是strptime函式執行后再設定tm_isdst為0

20191208:
    今天發現c++的throw比較消耗資源,即使沒觸發throw部分代碼,
我寫了兩個程式,代碼是一樣的,只是一個加了try catch,另一個沒有加,
編譯后運行,發現效率相差20%


20191210:
    今天使用callgrind檢測程式性能時,發現我有一個函式雖然有呼叫,但是在callgrind輸出結果卻看不到實際呼叫情況,
后來經過多次測驗,發現原來是這個程式被編譯器自動行內了,雖然我沒有指定inline,也沒有加-O,但編譯器還是將它行內了,


    兩個靜態庫的函式互相呼叫,會導致鏈接時無論怎么調整順序,都有可能報“找不到物件”,這時可以多鏈接幾次:
例如我有libA.a libB.a相互呼叫了,寫makefile時可這樣:-lA -lB -lA -lB,不過這只是臨時處理方案,實際上不應該出現這樣的相互呼叫的情況,


    linux訊息佇列好像沒有支持io多路復用的api,我設想了一個解決方案:
啟動一個專門的讀執行緒,使用阻塞讀訊息佇列,如果讀到了訊息,則發送一個信號給主行程監聽的句柄(例如匿名管道)

20191211:
    最后生產資料庫空間告警,只能把一些不常用的流水表做壓縮,以節省空間,幸好oracle提供了壓縮表的功能,

20191212:
    最近半年做了一個查詢庫同步的功能,程序還是很折騰的:
最開始打算直接使用goldengate同上交易庫的表和查詢庫的表,這是最方便的,
但是運維團隊說沒有購買這個工具,而且有安全問題,于是只能作罷,
后來又想著在業務庫表加上觸發器,把修改內容登記到一個日志表,再寫一個程式根據日志表同步資料到查詢庫,
但運維團隊又說不能加觸發器,因為觸發器影響性能,
之后有同事提出使用物化視圖,但我查了一下網上,oracle的物化視圖功能bug很多,沒建議,
最后偶然間,我查proc開發檔案時發現oracle提供了一種returning into的語法,可以回傳update/insert修改后記錄的內容,
于是最后決定:
1 并且給業務表增加修改時間欄位,insert或update時順便更新這個欄位,
2 在所有修改資料庫流水表的代碼增加returning into子句,把修改結果查詢回來,
3 把回傳的記錄發給同步行程,同步行程把記錄merge到查詢庫的表
4 為防止順序錯亂,同步查詢庫時需要加上判斷,如果修改時間比資料庫記錄的時間早,則不處理


20191216:
    檔案編碼不是檔案的屬性之一,這是很多人沒搞清楚的,他們往往會說“我檔案已經保存成gbk編碼,為什么傳到linux上打開還是亂碼”
其實問題就是檔案編碼不是檔案的屬性,linux上的檔案工具打開檔案時只能“猜測”檔案的編碼,如果它猜錯了,顯示就是亂碼,

20191217:
    邏輯尺:一個欄位,其中的各個位,由我們自己規定為0、1, 然后,用這一串0、1,依次去選擇兩種操作, 這個位元組,往往有人稱之為邏輯尺,

20191218:
    今天用proc編譯.pc檔案時出現core,看原因是段錯誤,
后來檢查一下,是由于檔案路徑太長,超過100個字符,觸發proc的bug


20191219:
    vim顯示不了回車符解決方法:vi -b

    vim輸入回車符方法:按住ctrl,再按v,再松開v按m

20191220:
    今天使用loadrunner壓測的程序中,報了不少"server has shut down the connection"的錯誤
觀察被壓測機器的接入程式,卻沒有發現例外,
    猜測是由于客戶端機TIME_WAIT太多造成的,不過修改后也沒多大改善,具體原因暫時還不知道


20191223:
    Disql是DM資料庫自帶的資料庫命令列客戶端工具,類似于sqlplus,不過做得不太好,
今天隨便試用了一下,就發現一個bug:進入disql后,如果不執行sql,直接按ctrl + c,會導致程式退出

20191225%08s,不是用0左補齊,而是用空格

20191226:
    oracle在多個會話查詢同一條記錄,容易出現LanchFree競爭事件


20191227:
    今天做非功能測驗,發現有一個交易跑一會tps就急劇下降,一開始我以為受清理日志影響,但后來把日志清理停了也一樣,
觀察vmstat輸出,tps下降時cpu使用wait的資料急劇上升,并且so也上升,猜測是由于記憶體換頁影響,使用ps aux www觀察,發現行程占用的記憶體大漲,

    iostat -x 2 5 # 每隔2秒列印io資訊 共5次



20191228:
    gdb打開core檔案,使用where發現堆疊例外,有一些函式根本不可能呼叫到,但卻顯示在輸出里面,
    后來發現core檔案生成時間比程式的修改時間還早,說明程式被修改過,后來我找了修改前的程式,重新用gdb除錯,這里where輸出就正常了,
    

20191230:
    今天啟動業務系統時出現有一些行程打開監聽埠時失敗,重啟時就好了,
仔細分析日志,發現問題是某些行程使用的隨機埠正好與監聽埠沖突了,

20191231:
    今天壓測時,發現tps突然下降,看vmstat,bi突然增加,wa增加,查看free,發現buffer突然減少,原來是有行程占用了太多記憶體導致的,

20200106:
    今天做非功能測驗時,發現資料庫很多"cursor: pin S wait on X"的等待事件,
百度查了一下,出現這個等待事件的原因很多,其中一個比較常見的情況是資料庫硬決議sql太多,
但我們系統高并發的sql都是使用系結變數的,理論上不應該出現很多硬決議,所以當時認為不是這個問題,(其實當時應該檢查一下硬決議次數再下結論)
后來偶然間發現有一些20年的流水表沒建,導致sql執行時出現"table or veiw not exist"的錯誤,這才明白過來為什么會有很多硬決議,
后來把表建好后再跑就沒這個等待事件了,



20200107:
    看網上的實驗說是rac切換時,該節點沒提交事務會自動回滾
    如果應用此時不進行rollback操作,再執行其他陳述句(包括commit)都會報ora-25402


20200108:
    loadrunner引數取隨機值設定方法:
Select next row: Random
Update Value On: Each iteration


20200109:
    查看系統在監聽的埠和對應程式名:netstat -anp|grep LIS


20200110:
    資料庫緩慢,執行
         set linesize 240
         col sid format 9999
         col s# format 99999
         col username format a15
         col event format a30
         col machine format a20
         col p123 format a18
         col wt format 999
         col SQL_ID for a18
         alter session set cursor_sharing=force;
            SELECT  
             S.SID,
             S.SERIAL# S#,
             P.SPID,
             NVL(S.USERNAME, SUBSTR(P.PROGRAM, LENGTH(P.PROGRAM) - 6)) USERNAME,
             S.MACHINE,
             S.EVENT,
             S.P1 || '/' || S.P2 || '/' || S.P3 P123,
             S.WAIT_TIME WT,
             NVL(SQL_ID, S.PREV_SQL_ID) SQL_ID
              FROM V$PROCESS P, V$SESSION S
             WHERE P.ADDR = S.PADDR
               AND S.STATUS = 'ACTIVE'
               AND P.BACKGROUND IS NULL;

    等待事件sga:allocation forcing component growth

20200217:
    今天安裝redis時發現一些語法比較奇怪的腳本,上網查了一下,原來是tcl腳本
百度了一下,介紹這樣的:“Tcl 是一種 腳本語言, 由John Ousterhout創建, TCL很好學,功能很強大,TCL經常被用于 快速原型開發,腳本編程, GUI和測驗等方面,”,TCL念作“踢叩” "tickle"
    以后有機會要了解一下


20200220:
    make install時可以臨時指定安裝目錄,make PREFIX=/home/huangcihui/local install

20200225:
    今天測驗redis性能時偶然發現redis服務設定了密碼,但運行redis-benchmark時沒輸入密碼引數結果也能跑成功,
后來研究了一下代碼才發現,redis-benchmark工具默認對回傳結果不做檢查,需要加上-e引數,才會檢查redis命令執行結果是否成功,

20200228:
    今天發現在高并發情況下,oracle的merge陳述句也可能會出現主鍵沖突,之前在低并發情況時一直用merge一次完成INSERT+UPDATE,避免主鍵沖突,

20200229:
    今天同事反映,生產上有一些交易被拒絕,報20200229日期非法,但今年是閏年,理論上不應該出現這個問題,而且奇怪的是不是所有交易都被拒絕,后來查了一下代碼,里面有這樣的代碼:
    char year[5];
    strcpy(year, dateTime, 4);
    if (IsLeap(atoi(year)) { ... }
    于是明白了,程式里面對于year沒有做初始化,導致有時atoi結果出現例外,導致程式判斷閏年錯誤,

20200302:
    ps aux www|grep -E 'TTY|redis',這樣可以保留ps輸出的標題


201200303:
    當你使用sudo去執行一個程式時,處于安全的考慮,這個程式將在一個新的、最小化的環境中執行,也就是說,諸如PATH這樣的環境變數,在sudo命令下已經被重置成默認狀態了,
    要想改變PATH在sudo會話中的初始值,用文本編輯器打開/etc/sudoers檔案,找到”secure_path”一行,當你執行sudo 命令時,”secure_path”中包含的路徑將被當做默認PATH變數使用, 


    sudo -v 延長密碼有效期限5分鐘,這樣就可以臨時省去sudo輸入密碼的麻煩



20200304:
    redhat的屏保居然是向上拖動的,不是像windows一樣點擊自動消失的,
開機后等好久一直停留在時間界面,點了沒反應,我一直以為開機沒完成,,,

20200305:
    新安裝的redhat默認啟動是進入圖形界面,可以執行命令
systemctl set-default multi-user.target,這樣重啟后優先進入命令列界面
如果以后需要恢復回來,則執行systemctl set-default graphical.target即可
    臨時命令列切換至桌面命令: init 5
    臨時桌面切換至命令列命令: init 3

20200308:
    redhat配置網卡自動連接,并使用dhcp配置網路地址方法:
需要修改配置/etc/sysconfig/network-scripts/ifcfg-<網卡名稱>
假設網卡名字叫eth0,則修改/etc/sysconfig/network-scripts/ifcfg-eth0
將BOOTPROTO改為dhcp,ONBOOT改為yes 
    修改后使用ifup eth0啟動連接

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/56853.html

標籤:C++

上一篇:C++運算子多載

下一篇:C語言筆記 08_函式指標&回呼函式&字串&結構體&位域

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more