主頁 > 企業開發 > 高德引擎構建及持續集成技術演進之路

高德引擎構建及持續集成技術演進之路

2020-09-23 06:38:40 企業開發

 

01 背景

由于導航應用中的地圖渲染、導航等核心功能對性能要求很高,所以高德地圖客戶端中大量功能采用 C++ 實作,隨著業務的飛速發展,僅地圖引擎庫就有40多個模塊,工程配置極其復雜,原有的構建及持續集成技術已無法滿足日益增長的需求變化,

除了以百萬計的代碼行數帶來的復雜度外,高德地圖客戶端中的 C++ 引擎庫工程(以下簡稱引擎庫)的構建和持續集成還面臨以下幾個挑戰:

  • 支持多團隊協作:多團隊意味著多作業系統多 IDE ,降低不同作業系統和不同 IDE 下的工程配置的難度是重點要解決的難題之一;
  • 支持多業務線定制:引擎庫為手機、車機、開放平臺等業務線提供支持,而各個業務線的訴求不同,所以需要具備按功能構建的能力;
  • 支持車機環境:在諸多業務線中,高德地圖有一個非常特殊的業務線,即車機(AMAP AUTO),車機直接面對各大車廠和眾多設備商,環境多為定制化,構建工具鏈各式各樣,如果針對每個車機環境都定制一套構建組態檔,那么其維護成本將非常高,所以如何用一套構建配置滿足車機的多樣化構建需求成為亟需解決的問題;

此外,由于歷史原因,引擎庫中原始碼和依賴庫混雜,都存放于 Git 倉庫中,這樣會帶來兩個問題:

  • 隨著構建次數不斷增加,Git 倉庫越來越大,代碼與依賴庫檢出越來越慢,極大影響本地開發以及打包效率;
  • 缺乏統一管理,依賴關系混亂,經常出現因為依賴問題而導致的構建失敗,或者雖然構建成功但運行時發生錯誤的情況;

上述的挑戰和歷史遺留問題嚴重阻礙了研發效能的提升,為此,我們對現有的構建及持續集成工具進行了深入的研究和分析,并結合自身的業務特性,最終發展出高德地圖 C++ 本地構建工具 Abtor 和持續集成工具 Amap CI ,

 

02 本地構建

 

現有工具分析

 

C++ 是一門靠近底層的語言,不同的硬體、作業系統、編譯器,再加上交叉編譯,導致 C++ 構建的難度非常高,針對這些問題,C++ 社區涌現出許多優秀的構建工具,比如大名鼎鼎的 Make 和 CMake ,

Make,即 GNU Make ,于1988年發布,是一個用來執行 Makefile 的工具,Makefile 的基本語法包括目標、依賴和命令等,使用程序中,當某些檔案變了,只有直接或者間接依賴這些檔案的目標才需要重新構建,這樣大大提升了編譯速度,

Make 和 Makefile 的組合可以看作專案管理工具,但它們過于基礎,在跨平臺的使用方面有很高的門檻和較多的限制,此外大專案的構建還會遇到 Makefile 嚴重膨脹的問題,

CMake 產生于2000年,是一個跨平臺的編譯、測驗以及打包工具,它將組態檔轉化為 Makefile ,并運行 Make 命令將原始碼編譯成可執行程式或庫,CMake 屬于 Make 系列,組態檔比 Makefile 具有可讀性,支持跨平臺構建,構建性能高,

但是 CMake 也有兩項明顯不足,一是組態檔的復雜度遠高于其它現代語言,對于 CMake 語法初學者有一定的學習成本,二是與不同 IDE 的配合使用不夠友好,

可以看出 Make 和 CMake 的抽象度還是比較低,從而對構建人員的要求過高,為了降低構建成本,C++ 社區又出現了一些新的 C++ 構建工具,現在使用較廣泛的包括 Google 的 Bazel 和 Ninja ,以及 SCons ,這些工具的特點和不足如下:

111.jpg

經過上述對現有 C++ 構建工具的研究和分析,可以得出每個工具既有所長又有不足的結論,再考慮到高德地圖引擎庫工程面臨的挑戰和歷史遺留問題,我們發現以上工具沒有一個可以完美契合業務需求,且改造成本非常高,所以我們決定基于 CMake 自建 C++ 本地構建工具,即現在引擎庫工程使用的 Abtor ,

Abtor

首先,我們需要解釋一個問題,即 Abtor 是什么?

Abtor 是一個 C++ 跨平臺構建工具,Abtor 采用 Python 撰寫構建腳本,生成 CMake 組態檔,并通過內置 CMake 組件生成構建檔案,最終產出可執行程式或庫,它抽象出構建描述,使得復雜的編譯器和連接器對開發者透明;它提供強大的內置功能,從而有效的降低開發者撰寫構建腳本的難度,

其次,我們需要闡述一個問題,即Abtor的構建流程是什么?

222.png

如上圖所示,Abtor 構建的整個流程為:

  • 撰寫 Abtor 構建腳本;
  • 決議 Abtor 構建腳本;
  • 檢測依賴關系,識別沖突,并從阿里 OSS 上下載所需依賴;
  • 生成CMakeLists.txt,并通過內置的 CMake 生成 Makefile 檔案;
  • 編譯,鏈接,生成對應平臺的目標檔案;
  • 將目標檔案發布到阿里 OSS ;

除此之外,還增加了控制訪問發布庫權限的功能,用于保證發布庫的安全,

最后,我們需要探討一個問題,即Abtor解決了什么?

在開篇背景中,我們提到阻礙研發效能的一些挑戰和問題,這就是 Abtor 需要解決的,所以 Abtor 具備以下特點:

  • 更廣泛的跨平臺:支持 MacOS 、iOS、Android、 Linux、Windows、QNX 等平臺;
  • 有效的多團隊協作:較好得與 IDE 結合,并支持一套配置生成不同專案工程,從而達到工程配置一致化;
  • 高定制化:支持工具鏈及構建引數的靈活定制,并通過內置工具鏈配置為車機復雜的構建提供強有力的支持;
  • 原始碼與依賴分離:支持原始碼依賴與庫依賴,原始碼通過Git管理,構建庫存放于阿里云,原始碼與產物完全分離;
  • 良好的構建性能:快速構建大型專案,從而提高開發效率;

從上述特點可看到,Abtor 有效地解決了已有的構建工具在高德業務中面臨的痛點,但是冰凍三尺,非一日之寒,Abtor 也是在不斷地完善中,下面重點介紹一下 Abtor 發展程序中遇到的三個問題,

工程配置一致化

在日常開發程序中,工程專案的除錯作業尤為重要,高德地圖客戶端中的 C++ 引擎庫工程的開發人員涉及幾個部門和諸多小組,這些組擅長的技術堆疊,使用的平臺和習慣的開發工具都大為不同,如果針對每一個平臺都單獨建立相應的工程配置,那么作業量及后續維護成本可想而知,

基于以上原因,Abtor 內置與 IDE 結合的功能,即開發者可以通過一套配置并結合 Abtor 命令一鍵生成工程配置,實作在不同平臺的工程配置的一致化,工程配置一致化為引擎庫開發帶來以下幾個收益:

  • 命令簡單,降低學習成本,開發者只需熟記 abtorw project [IDE name];
  • 組態檔不會因為 IDE 的增加而迅速膨脹,開發者更換構建命令,比如 abtorw project xcode 或者abtorw project vs2015,即可生成對應的專案工程;
  • 有利于部門間的協作及新人的快速融入,開發者可以根據喜好選擇 IDE 進行開發,大大提高開發效率;
  • 目前Abtor支持的IDE有 Xcode、Android Studio、Visual Studio、Qt Creator、CLion等,

 

復雜車機環境的構建

 

作為高德地圖一條非常重要的業務線,車機面對的構建環境復雜多變,廠商往往會自行定制工具鏈,如果每接入一個設備,所有工程專案都需要修改組態檔,那么這個成本還是非常高的,為了解決這個問題,Abtor 提供兩種做法:

  • 內置工具鏈配置:對于開發者完全透明,他不需要修改任何配置即可構建相應平臺的產物;
  • 支持自定義配置插件:開發者按照規則撰寫配置插件,構建時 Abtor 會檢測插件,并根據設定的工具鏈及構建引數進行構建;

除此之外,我們對所有的車機環境進行了 Docker 化處理,并通過 Docker 控制中心統一管理車機 Docker 環境的上線與下線,再利用上述 Abtor 的內置工具鏈配置功能內置車機構建引數,實作開發者無感知的環境切換等操作,有效地解決了復雜車機環境的構建問題,

基于 Docker 的車機構建主要步驟如下:

  • 工具鏈安裝:一般由廠商提供,我們會將該工具鏈安裝到基礎 Docker 鏡像中;
  • Docker 發布:將鏡像發布到 Docker 倉庫;
  • Abtor 適配:一次性適配工具鏈,并內置配置,開發者可通過 Abtor 版本升級使用該配置;
  • 服務配置更新:由 Jenkins 管理,支持分批更新 Abtor 版本,不影響當下編譯需求;
  • 服務監控: 由 Jenkins 管理,定時檢測服務狀態,例外態的 Docker 服務將自動被重啟;

基于Docker的車機構建關系圖如下:
333.jpg

依賴管理

依賴問題是所有構建工具都避免不了的問題,在這其中,菱形依賴問題尤為常見,如下圖所示,假設 A 依賴了 B 和 C ,B 和 C 又分別依賴了不同版本的 D,而 D 之間只存在很小的差異,這是可以編譯通過的,但最終在運行時可能會出現意想不到的問題,

如果沒有一種機制來檢測,菱形依賴是很難被發現,而產生的后果又可能是非常嚴重的,比如導致線上出現大面積的崩潰等,所以依賴問題的分析與解決非常重要,

444.png

當下,市面上 Java 有比較成熟的依賴管理解決方案,如 Maven 等,但 C++ 并沒有,為此 Abtor 專門建立依賴管理的機制來確保編譯的正確性,

Abtor 的依賴管理是怎么做的呢?這里提供一個思路供大家參考:

  • 建立 Abtor 服務端,用做庫發布,以及處理依賴關系;
  • 每個庫在云端構建完,都會把庫依賴的版本資訊存放于云端資料庫中;
  • 本地/云端構建前 Abtor 會決議出所有依賴庫的版本資訊;
  • 遞回查找這些子庫對應的依賴資訊,即可羅列出所有依賴庫的資訊;
  • 檢測依賴庫串列中是否存在不同版本號的相同庫名:
  • 如果沒有相同庫名,則繼續執行構建;
  • 如果有相同庫名,則說明依賴庫之間存在沖突問題,此時中斷構建,并顯示沖突的庫資訊,待開發者解決完沖突后方可繼續執行構建;

根據上述思路,我們保證了庫依賴的一致性,避免了菱形依賴問題,另外,如果某個庫被其它庫所依賴且有更新,那么依賴它的庫也應當隨之構建,以確保依賴的一致性,這種對依賴構建的觸發更新我們放到 Amap CI 上實作,在第三節會進行詳細介紹,

工程實踐

在介紹完 Abtor 的一些基本原理后,我們將介紹 Abtor 在日常開發中是如何使用的,

下圖是 Abtor 工程專案的目錄結構,其中有兩類檔案是開發者需要關心的,一類是源檔案目錄(src),一類是 Abtor 核心組態檔(abtor.proj),

abtor_demo
├── ABTOR
│   └── wrapper
│       ├── abtor-wrapper.properties # 組態檔,可指定Abtor版本資訊
│       └── abtor-wrapper.py         # 下載Abtor版本并呼叫Abtor入口函式
├── abtor.proj                       # Abtor核心組態檔
├── abtorw                           # Linux/Mac下的初始執行腳本
├── abtorw.bat                       # Windows下的初始執行腳本
└── src
    └── main.c                       # 要編譯的源檔案

 

源檔案目錄的組織形式與 Make 系列構建工具沒有太大區別,下面重點看一下Abtor核心組態檔:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 以下內容為python語法

# 指定編譯的原始碼
header_dirs_list = [abtor_path("include")]    # 依賴的頭檔案目錄
binary_src_list = [abtor_path("src/main.c")]  # 原始碼

cflags = " -std=c99 -W -Wall "
cxxflags = " -W -Wall "

# 指定編譯二進制
abtor_ccxx_binary(
  name = 'demo',
  c_flags = cflags,
  cxx_flags = cxxflags,
  deps = ["add:1.0.0.0"],                        # 指定依賴的庫資訊
  include_dirs = header_dirs_list;
  srcs = binary_src_list
)

從上圖可以看出,Abtor核心組態檔具有以下幾個特點:

  • 采用Python撰寫,易上手;
  • 抽象類似 abtor_ccxx_binary 等的構建描述,降低使用門檻;
  • 提供諸如 abtor_path 等的內置功能,提高開發效率;

通過以上的對源檔案目錄組織及 Abtor 核心組態檔撰寫,我們就完成了專案的Abtor配置化,接著可以通過Abtor內置的命令構建、發布或直接生成專案工程,我們相信,即使開發者不是很精通構建原理,依然可以無障礙地使用Abtor進行構建與發布,

 

03 持續集成

 

面臨的問題

如下圖所示,整個開發作業流程可分為幾個階段:編碼->構建->集成->測驗->交付->部署,在使用Abtor解決本地構建遇到的一系列挑戰與問題后,我們開始將目光轉移到了整個持續集成階段,

 

555.png

 

持續集成是指軟體個人研發的部分向軟體整體部分交付,頻繁進行集成以便更快地發現其中的錯誤,它源自極限編程(XP),是 XP最初的12種實踐之一,對于引擎庫來說,持續集成方案應該具備一次性批量構建不同平臺不同架構目標檔案的能力,同時也應當具備運維管理和訊息管理的能力等,

最初高德引擎庫使用 Jenkins 進行持續集成,因為引擎庫開發采用在 Git 倉庫上拉取分支的方式進行版本管理,所以每次版本迭代都需要手動建立 Jenkins Job,修改相應腳本,另外還需要額外搭建一個依賴庫關系的 Jenkins Job 做聯動編譯,

假設有100個專案,那么每個版本迭代都需要手動創建101個 Jenkins Job ,每次版本迭代都重復類似的操作,中間需要大量的協調作業,隨著迭代版本越來越多,這些 Jenkins Job 變得不可維護,這是 Jenkins 持續集成方案在高德引擎庫開發程序中遇到的非常嚴重的問題,

基于上述原因,我們迫切得需要這樣一個持續集成系統:開發者不用維護Jenkins,不需要部署構建環境,可以不了解構建細節,只需要通過某個觸發事件就能夠構建出所有平臺的目標檔案,于是我們決定自建持續集成平臺,即 Amap CI,

Amap CI

Amap CI 平臺使用Gitlab的Git Webhook實作持續集成,其中,Gitlab 接收開發者的 tag push 事件,回呼 CI平臺的后臺服務,然后后臺服務根據構建機器的運行情況進行任務的分發,當構建任務較多時,CI平臺會等待直到有構建資源才進行任務的再分配,

Amap CI 平臺由任務管理、Jenkins管理、構建管理、通知管理、網頁前端展示等幾部分組成,整體架構圖如下:

 

666.png

 

通過 Amap CI 平臺,我們達到了以下幾個目的:

  • 可擴容:所有構建機器通過注冊的方式接入,構建機器擴容變得非常容易,減輕構建峰值帶來的壓力;
  • 可視化:Abtor Server 對于開發者是透明的,CI 平臺與 Abtor Server 互動,為開發者提供沖突檢查、依賴查看及庫下載等可視化功能;
  • 智能化: CI 平臺內置標準的 Jenkins Job 構建模板,開發者不感知這些模板,也無須做任何的修改,他們只需要通過 Git 提交一個 tag 資訊即可實作全平臺的構建,從而實作一鍵打 tag 構建;
  • 自動化:服務分析 Gitlab hook tag 的 push 資訊并拉取代碼,然后決議對應的組態檔和要構建的所有平臺資訊,根據這些資訊CI平臺分配構建機器,并執行 Abtor 命令進行構建與發布,所有這些皆自動完成;
  • 即時性:構建啟動后會發送釘釘訊息,訊息除了概要資訊外還附加了構建的鏈接等,開發者可以點擊鏈接跟蹤進度情況,構建成功或失敗也都會發送訊息,從而使得開發者可以及時進行下一步作業或處理構建錯誤;
  • 可擴展:CI平臺提供可擴展的對接方式,方便高德或阿里的其它平臺對接,比如泰坦平臺、CT平臺、Aone等,從而實作編碼、構建、測驗和發布的開發倍訓;

在上述目的中,對 Amap CI 平臺最重要的是自動化,下面我們重點介紹一下自動化中的整樹聯動編譯,

777.png

整樹聯動編譯

在第二部分中我們提到了一個問題,即如果某個庫被其它庫所依賴且有更新,那么依賴它的庫也應當隨之構建,以確保依賴的一致性,這是構建自動化的關鍵點之一,Amap CI 采用整樹聯動編譯的方案來解決這個問題,

開發者在CI平臺上建立對應的版本構建樹,構建樹中羅列了各個庫之間的構建順序,如下圖所示,CI平臺會根據這棵構建樹進行構建,被依賴的庫優先構建,完成后再自動觸發其上級的庫構建,以此類推,最終形成一棵多叉樹,在這棵多叉樹上,從葉子節點開始按層級順序逐級并發構建對應的庫,這就是整樹聯動編譯,

根據上述思路,我們保證了持續集成時的依賴一致性,開發者只需關心自己負責的庫,打個 tag ,即可觸發生成所有依賴該庫的庫,從而避免了依賴不一致的問題,

工程實踐

在介紹完 Amap CI 的一些基本原理后,我們將介紹日常開發中應該如何使用Amap CI,

一個新的工程專案在集成到 Amap CI 平臺時,首先需要將CI平臺的 web hook 網址增加到 Gitlab 的配置中,然后撰寫組態檔 CI_CONFIG.json ,至此一個新的專案已集成完成,非常簡單,下面我們重點介紹一下 CI_CONFIG.json ,

CI_CONFIG.json 是核心組態檔,一次撰寫,無需再修改,它的結構如下:

CI_CONFIG.json DEMO:(json)
{
    "mail":"[email protected]",                    # 郵件通知
    "arch":"Android,iOS,Mac,Ubuntu64,Windows",        # 構建的平臺
    "build_vars":"-v -V",                             # 構建引數
    "modules":{                                       # 構建的模塊串列
        "amap":{                                      # 模塊名為amap
            "features":[                              # 功能串列
                {
                    "name":"feature1",                # 設定功能名為feature1
                    "macro":"-DFEATURE_DEMO1=True"    # 宏控:FEATURE_DEMO1
                },
                {
                    "name":"feature2",               # 設定功能名為feature2
                    "macro":"-DFEATURE_DEMO2=True"   # 宏控:FEATURE_DEMO2
                }
            ]
        },
        "auto":{                                    # 模塊名為auto
            "features":[                            # 功能串列
                {
                    "name":"feature1",              # 設定功能名為feature1
                    "macro":"-DFEATURE_DEMO1=True"  # 宏控:FEATURE_DEMO1
                },
                {
                    "name":"feature3",             # 設定功能名為feature3
                    "macro":"-DFEATURE_DEMO3=True" # 宏控:FEATURE_DEMO3
                }
            ]
        }
    }
}

 


從上圖可以看出,組態檔描述了郵件通知、構建的平臺、構建引數等資訊,同時還為多業務線定制提供了良好的支持,
Amap CI 構建時讀取上述檔案,決議不同專案中配置的宏,并通過引數傳遞給 Abtor ,另一方面開發者在代碼中利用這些宏進行代碼隔離,構建時會根據這些宏選擇對應的原始碼進行編譯,從而支持多條業務線不同的需求,達到代碼層面的最大復用,

 

目前 Amap CI 接入的專案數有幾百個,編譯的次數達到幾十萬次級別,同時在構建性能和構建成功率方面相比之前都有了大幅度的提高,現在仍舊不斷有新的專案接入到構建平臺上,可以說 Amap CI 平臺是高德地圖客戶端 C++ 工程快速迭代開發的堅實保障,

 

04 未來展望

 

從2016年年中調研現有構建工具算起,到現在三年有余,三年很長,足以讓我們將構想變成現實,足以讓我們不斷完善 Abtor ,足以讓我們發展出 Amap CI ,三年又很短,對于一個系統開發生命周期而言,這僅僅是萌芽階段,我們的征途才剛剛開始,

 

關于未來,我們的規劃是向開發倍訓方向發展,即打通編碼、構建、集成、測驗、交付和部署等各個環節中的鏈路,解決業務開發倍訓的問題,實作整個開發流程自動化,進一步把開發者從繁瑣的流程中解放出來,使得這些人員有精力去做更有價值的事情,

 

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

標籤:Html/Css

上一篇:負邊距與雙飛翼布局

下一篇:關于 JS this

標籤雲
其他(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)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more