<input id="ohw05"></input>
  • <table id="ohw05"><menu id="ohw05"></menu></table>
  • <var id="ohw05"></var>
  • <code id="ohw05"><cite id="ohw05"></cite></code>
    <label id="ohw05"></label>
    <var id="ohw05"></var>
  • 干貨十足,驚為佳作,四年劃水經驗總結(持續更新)

    21.使用MQTT通信

    前期需要第三方服務端,我選擇了EMQ代理服務。主要使用瀏覽器打開 http://localhost:18083,能夠看見連接、主題等等,方便測試

    當前我推薦(依賴庫)Qmqtt 。編譯好了之后,直接在qtcreator中引用

    win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/ -lQt5Qmqtt
    else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/ -lQt5Qmqttd
    else:unix: LIBS += -L$$PWD/lib/ -lQt5Qmqtt
    
    INCLUDEPATH += $$PWD/include
    DEPENDPATH += $$PWD/include

    代碼示例:(連接信息僅需IP+端口即可)

        QMQTT::Client *client = new QMQTT::Client(QHostAddress::LocalHost, 1883);
        client->setClientId("lzw");
        client->setUsername("admin");
        client->setPassword("public");
        client->connectToHost();

    注意一下Qos:

    QOS0不可靠,因此適合大量數據的傳輸,因為很大量的數據,完全避免不丟包是很難的(網絡環境、現實環境);

    QOS1可靠,一般的場景夠用,因為總能接到數據嘛。缺點就是 “可能造成” 一條數據,接收到了多次;

    QOS2嚴格可靠,保證相同的消息只接收一條,耗性能。

    20.使用Redis數據庫

    前期準備工作,需要下載解壓Redis的Windows安裝包。現在我們開始體驗:

     當前我推薦(依賴庫) acl-dev/acl。編譯好了之后,直接在qtcreator中引用

    INCLUDEPATH += Depends\include
    LIBS += -L$$DESTDIR -llib_acl_cpp_d

    代碼示例:(連接信息僅需IP+端口即可)(這里加入鍵值對:test_key -  test_value)

    
    
    #include "acl_cpp/lib_acl.hpp"
    int run()
    {
        // init socket module for windows
        acl::acl_cpp_init();
    
        const char* redis_addr = "127.0.0.1:6379";
        int conn_timeout = 10, rw_timeout = 10;
    
        // the redis client connection
        acl::redis_client conn(redis_addr, conn_timeout, rw_timeout);
    
        const char* key = "test_key";
    
        // test redis STRING command
        // bind redis_string command with redis connection
        acl::redis_string cmd_string(&conn);
        test_redis_string(cmd_string, key);
    
        // test redis KEY command with the same redis connection
        acl::redis_key cmd_key(&conn);
        test_redis_key(cmd_key, key);
    
        return 0;
    }

    19.了解一下memcpy_s,以便看懂他人代碼

    某個程序的穩定型,主要還是看代碼邏輯,雖然有這些安全函數,但也不能過分依賴

        char in_src[10]{0}; char in_no = -1 * -1;
        in_src[in_no]= -100;
    
        int in_desLen = 9;
        char *in_des = new char[in_desLen];
        QByteArray in_checkValue = QByteArray::fromRawData(in_des, in_desLen);
        qDebug()<<in_checkValue.length();
    
        // in_desLen>=in_srcLen時,copy成功,返回值0
        // in_desLen<in_srcLen時,copy失敗,整個數組賦值為0,返回值非0
        auto in_rlt = memcpy_s(in_des, in_desLen, in_src, 10);
        qDebug()<<in_rlt;
    
        in_checkValue = QByteArray::fromRawData(in_des, in_desLen);
        qDebug()<<in_checkValue.length();

    18.使用深拷貝,更改對象所屬權

    /***************************************************************
    * @brief        獲取深拷貝對象,跨線程使用
    * @date         2022-01-23
    ***************************************************************/
    stuLog *TestHelper::GetCloneObj(stuLog *in_orgInfo)
    {
        stuLog *in_newInfo = new stuLog();
        *in_newInfo = *in_orgInfo;
        return in_newInfo;
    }

    注意:所定義類中不能含有指針

    17.使用線程安全隊列,控制界面繪圖速度

    //模擬標識
    int g_num = 1;
    
    /***************************************************************
    * @brief        模擬其他組件產生數據
    * @date         2022-01-22
    ***************************************************************/
    void TestHelper::RunExecWrite()
    {
        while(1)
        {
            //if (g_num>50) break;
    
            stuLog in_info;
            in_info.id = g_num++;
            in_info.name = "hello www";
    
            this->AddData(in_info);
            QThread::msleep(20);
        }
    }
    
    /***************************************************************
    * @brief        實際應用,其他組件傳來數據
    * @date         2022-01-22
    ***************************************************************/
    void TestHelper::AddData(stuLog &in_data)
    {
        bool in_rlt = m_queue->push(in_data);
        if (!in_rlt)
            qDebug()<<QDateTime::currentDateTime().toString("mm:ss.zzz")<<"AddData:"<<in_rlt<<" "<<in_data.id;
    }
    
    /***************************************************************
    * @brief        實際應用,在界面上消費(避免界面卡頓,用戶體驗差)
    * @date         2022-01-22
    ***************************************************************/
    void TestHelper::RunExecRead()
    {
        while(1)
        {
            QList<stuLog> in_list;
    
            if (m_queue->length()==0)
            {
                // 信號量阻塞,直到有新數據收到
                stuLog in_info; m_queue->pop(in_info);
                // 有新數據來了
                in_list.append(in_info);
            }
    
            for(qint32 in_idx=0; in_idx<m_queue->length(); ++in_idx)
            {
                stuLog in_info;
                bool in_rlt = m_queue->pop(in_info);
                if (in_rlt) in_list.append(in_info);
            }
    
            qDebug()<<QDateTime::currentDateTime().toString("mm:ss.zzz")<<"RunExecRead:"<<in_list.length();
    
            //SubData(in_list);
    
            QThread::msleep(200);
        }
    }

    16.kafka入門實踐(默認需要安裝java服務端)

    客戶端可以選擇java,csharp,c++。支持跨平臺,客戶端上線數據回滾,畢竟是分布式持久化神器哈。

    使用時,一般先創建一個主題,客戶端(生產者)與客戶端(消費者)通過主題進行通信。

    它們之間的內部依賴關系如下。zkserver(java),kafka服務端(java),客戶端(生產者),客戶端(消費者)

    可執行程序目錄如下:

     關鍵代碼如下:

    1         static void Main(string[] args)
    2         {
    3             do
    4             {
    5                 Produce(GetKafkaBroker(), getTopicName());
    6                 System.Threading.Thread.Sleep(3000);
    7             } while (true);
    8         }
    1         static void Main(string[] args)
    2         {
    3             Consume(getKafkaBroker(), getTopicName());
    4         }

    15.C++實現類成員模板函數(自定義結構體)

    入口統一,模擬接收了很多報文,都將進行數據預處理,最后再將結果統一輸出,出口統一

    void TestTemplate::PrintSomething(const QString &in_recvMsg)
    {
        qDebug()<<in_recvMsg;
    
        TemplateA in_tplA; in_tplA.CarName = "LZW Car";
        HandleData<TemplateA>(&in_tplA);
    
        TemplateB in_tplB; in_tplB.PhoneName = "LZW Phone";
        HandleData<TemplateB>(&in_tplB);
    }
    
    template <typename T>
    void TestTemplate::HandleData(T *in_info)
    {
        QString in_rlt = "Nice";
    
        // 方式一
        if (std::is_same<T, TemplateA>::value)
        {
            TemplateA *in_tpA = (TemplateA*)(in_info);
            if (in_tpA)
            {
                qDebug()<<"CarName:"<<in_tpA->CarName;
                in_rlt.prepend(in_tpA->CarName);
            }
        }
    
        // 方式二
        QString in_className = typeid(in_info).name();
        if (in_className.contains("TemplateA"))
        {
            TemplateA *in_tpA = (TemplateA*)(in_info);
            if (in_tpA)
            {
                qDebug()<<"CarName:"<<in_tpA->CarName;
                in_rlt.prepend(in_tpA->CarName);
            }
        }
        else if (in_className.contains("TemplateB"))
        {
            auto in_tpB = (TemplateB*)(in_info);
            if (in_tpB) {
                qDebug()<<"PhoneName:"<<in_tpB->PhoneName;
                in_rlt.prepend(in_tpB->PhoneName);
            }
        }
    }
    
    template<typename T>
    T TestTemplate::GetObj(const T &in_info)
    {
        return in_info;
    }

    14.C++(qt)實現類似于CSharp的lambda查找(自定義結構體)

    主要避免了寫for循環,至于查找速度上,也快一點

    //1
    struct person
    {
        QString name;
        int age;
        QString note;
        int cost;
        person()
        {
    
        }
        person(const QString &in_name, int in_age)
        {
            name = in_name;
            age = in_age;
        }
        //2
        bool operator == (const person &in_item)
        {
            return name.compare(in_item.name) == 0;
        }
    };
    
    /***************************************************************
    * @brief        自定義結構體查找
    * @date         2021-12-29
    ***************************************************************/
    void FindDefineStuList()
    {
        QList<person> in_list;
        in_list.append(person("lzw1", 18));
        in_list.append(person("lzw2", 19));
        in_list.append(person("lzw3", 20));
    
        // 找這個人的年齡?
        person in_objAm; in_objAm.name = "lzw2";
        QList<person>::iterator in_rlt = qFind(in_list.begin(), in_list.end(), in_objAm);
        if (in_rlt!=in_list.end())
        {
            qDebug()<<in_objAm.name<<":"<<in_rlt[0].age;
        }
    }

    13.使用zmq業務數據交互通信(請求-應答模式)與并行計算通信(任務-管道模式)

    結合具體場景使用。

    12.使用zmq輕巧業務應用通信(發布-訂閱模式)

    結合具體場景使用。大部分用于數據分發的場景

    11.使用OSG-Earth玩轉三維地圖(離線加載)

    主要效果如下,由于個人對c++寵愛多一點,所以就沒玩 cesium.js,使用的傳統的cs桌面軟件形式

    10.使用QMapcontrol體驗輕量級的二維地圖(離線加載)

    由于直接依賴qt,所有用得簡潔輕便,傳統的cs桌面軟件形式

    9.快速輸出C++結構體成員名與值,類型?

    #include <iostream>
    #include <string>
    #include <typeinfo>
    
    //獲取變量的字面名字
    #define Name(X) #X   
    //打印變量的字面名字與值
    #define ShowName(X) {std::string xname=Name(X); \
    std::cout<<xname.substr(2,xname.size()-1)<<":"<<X<<std::endl; \
    }  
    //打印變量的類型
    function {
    int x=0; std::cout<<typeid(x).name()<<std::endl;
    }

    8.機器學習是選擇tensorflow還是tensorflow lite了?

    個人覺得還是結合實際場景進行選擇。

    TensorFlow 是谷歌開源的人工智能庫,有最完善的生態支持,是進行人工智能領域開發和科研的必備工具。主要還是桌面端,linux居多

    而TensorFlow Lite 是一種用于設備端推斷的開源深度學習框架,同樣也是跨平臺。看了一下現在的桌面QQ也在使用了,注意保護個人隱私了。

    7.基于QT插件系統,自定義開發業務框架?

    //! ------>當前框架系統已集成 **********內部組件通信、外部進程通信、寫日志、數據庫ORM********** ! <------//

    //! ------>近期將集成二維地圖插件<------//

    6.GIS,WGS84(世界通用坐標系)與GCJ02(火星坐標系)?

    WGS-84 到 GCJ-02 的轉換(即 GPS 加偏)算法是一個普通青年輕易無法接觸到的“公開”的秘密。

    目前可用于WGS84的共用地圖,谷歌衛星地圖、ArcGIS衛星地圖和必應衛星地圖

    目前可用于GCJ02的共用地圖,高德地圖(互聯網應用在本朝必須使用該坐標系)

    1、高德地圖:

    【境內】:GCJ-02 WGS-84——>GCJ-02(高德有接口提供,反過來沒有) 【境外】:暫不支持

    AMap 就是高德地圖,是高德地圖在納斯達克上市用的名字,主要面向互聯網企業或個人提供免費API服務
    MapABC 是高德集團底下的圖盟公司,主要面向大眾型企業或政府機關,并提供付費的有償服務
    Amap和MapABC,數據和服務都是共享的,所以Mapabc用Amap的API是正常的

    2、百度地圖

    【境內(包括港澳臺)】:BD09 在GCJ-02坐標系基礎上再次加密 支持WGS-84、GCJ-02轉換成BD09,反向不支持,并且批量轉換一次有條數限制 【境外】:WGS-84

    3、google地圖

    【境內】:GCJ-02 數據來源于高德,兩者互通 【境外】:WGS-84

    4、微軟Bing地圖:BingMap
    【全球統一】:WGS-84

    5、騰訊地圖:SoSo地圖
    【境內】:GCJ02

    坐標系知識回顧如下:

    WGS84

    WGS84坐標系是為GPS全球定位系統使用而建立的坐標系統,通過遍布世界的衛星觀測站觀測到的坐標建立,其初次WGS84的精度為1-2m。

    瓦片z=0,x=0,y=0,對應的坐標范圍是經度[-180,180],緯度[-85.05,85.05],對應的瓦片尺寸是256像素*246像素。

    經緯度坐標(lng,lat)轉瓦片坐標(tileX,tileY)的公式如下:

    tileX=int( (lng+180)/360*2^z)

    tileY=(1- arsinh(tan(lat*π/180))/π) *2^(z-1)

    其中z是zoom level,計算結果取整數。

    其中反雙曲正弦函數arsinh(x),等價于ln(x+(x^2+1)^0.5)。

    瓦片坐標(tileX,tileY)轉經緯度坐標(lng,lat)公式如下(計算結果為該瓦片對應的最小經度和最大緯度)

    lng=tileX/2^z * 360-180

    lat=arctan(sinh(π*(1-2*tileY/2^z)))*180/π

    其中,z是zoom level,雙曲函數sinh(x)=(e^x-e^(-x))*0.5。

    經緯度坐標(lng,lat)轉像素坐標(pixelX,pixelY)公式如下

    pixelX=(lng+180)/360*2^z*256%256

    pixelY=(1-ln(tan(lat*π/180)+sec(lat*π/180))/(2*π))*2^z*256%256

    公式中設定瓦片圖塊尺寸為256*256pixel,z是zoom level,web墨卡托平面坐標除以像素分辨率,再除以256取余就是像素坐標。

    瓦片坐標(tileX,tileY)的像素坐標(pixelX,pixelY)轉經緯度坐標(lng,lat)公式如下

    lng=(tileX+pixelX/256)/2^z*360-180

    lat=arctan(sinh(π-2*π*(tileY+pixelY/256)/2^z))*180/π

    其中,z是zoom level。

    GCJ02

    GCJ-02是由中國國家測繪局(G表示Guojia國家,C表示Cehui測繪,J表示Ju局)制訂的地理信息系統的坐標系統。凡是公開發布的商業互聯網地圖,一定要在此加密算法的基礎上進行發布,這樣一來地圖的坐標就與實地的坐標不相符了,于是大家把這種坐標戲稱為"火星坐標"。

    5.GIS,小數點度 轉 度分秒?

    //12.2436°  -->  12°14'36″
    QString convDecimaltoDMS(double in_dNum)
    {
        //返回小于或等于指定數字的最大整數
        int in_dValue = (int)floor(in_dNum);
        double x = (in_dNum-in_dValue)*60;
        int in_mValue = (int)floor(x);
        double in_sValue = (x-in_mValue)*60;
    
        //返回結果,字符串格式化,不區分經緯,NE-SW
        QString in_ret = QString("%1°%2′%3″").arg(in_dValue)
                .arg(in_mValue, 2, 10, QChar('0'))
                .arg((int)in_sValue, 2, 10, QChar('0'));
        return in_ret;
    }

    4.根據業務需要,如何進行三表查詢?

    前提條件:股市數據表:tbStockMarket(主表),股票詳情表:tbStockAttach,個人關注股票表:tbStockConcern

    業務需要:查看最近個人關注的某只股票的股市價格走勢,并帶有股票信息

    使用等值連接,SQL語句如下:

    SELECT
    A.ID, A.Name, A.Price, A.CurrentDate, B.Note, C.Grade
    FROM tbStockMarket AS A
    INNER JOIN tbStockAttach AS B ON (A.Code = B.Code)
    INNER JOIN tbStockConcern AS C ON (C.Code = B.Code)
    WHERE C.Code = '600039' ORDER BY A.CurrentDate

     成功執行該語句,符合預期

    SQL知識回顧如下:

    left join(左聯接) 返回包括左表中的所有記錄和右表中聯結字段相等的記錄 
    right join(右聯接) 返回包括右表中的所有記錄和左表中聯結字段相等的記錄
    inner join(等值連接) 只返回兩個表中聯結字段相等的行

    3.QTreeWidget排序后,如何使每行序號不發生改變?

    第一步:初始化首列為序號,并默認賦值

        QTreeWidgetItem *in_viewItem = new QTreeWidgetItem;
        in_viewItem->setData(0, 0, ++in_idx); //注釋:in_idx是最初的默認排序

    第二步:關聯信號槽,排序后人工重置序號

    connect(ui->tw_dataMarket->header(), &QHeaderView::sortIndicatorChanged,
                this, [=]() {
            for (int in_idx=0; in_idx<ui->tw_dataMarket->topLevelItemCount(); ++in_idx)
            {
                ui->tw_dataMarket->topLevelItem(in_idx)->setData(0,0,in_idx+1);
    
    
    } });

    效果如下:

    2.win下面同一套代碼,linux下編譯成功后,竟然找不到同級目錄的共享庫?

      在項目工程pro文件下,加上RPATH命令:

      unix:!mac: QMAKE_LFLAGS += -Wl,--rpath=./

      執行qmake,重新構建即可

    第一步:現象重現,找出哪個倒霉蛋

    第二步:走回理想狀態,破鏡重圓

    1.使用虛擬機之前還能和宿主機通信,后來突然就不行了,怎么回事?

      虛擬機指定的物理網卡和宿主機使用的物理網卡不一樣,需要修改虛擬機的物理網卡后重新啟動

    第一步:關閉虛擬機操作系統

    第二步:修改虛擬機的物理網卡,之后重新啟動

    第三步:打通任督二脈,狀態回升

     

    ---------------->版本迭代中,最近更新日期:2022-06-12,又是一年高考季<----------------

    //! *****工作已穩定,目前就職于成都愛科特。四年如一日,技術交流 -> qq郵箱 1358849798@qq.com,非誠勿擾***** !//


     
    posted @ 2021-09-24 09:55  李濤賢賢  閱讀(149)  評論(0編輯  收藏  舉報
    国产美女a做受大片观看