主頁 > 後端開發 > ?openGauss資料庫原始碼決議系列文章—— DeepSQL?

?openGauss資料庫原始碼決議系列文章—— DeepSQL?

2021-09-29 08:07:53 後端開發

???大家好,我是Gauss松鼠會,歡迎進來學習啦~???

上一篇介紹了 8.6 AI查詢時間預測的相關內容,本篇我們介紹“8.7 DeepSQL、8.8 小結”的相關精彩內容介紹,

8.7 DeepSQL

前面提到的功能均為AI4DB領域,AI與資料庫結合還有另外一個大方向,即DB4AI,在本章中,我們將介紹openGauss的DB4AI能力,探索通過資料庫來高效驅動AI任務的新途徑,

使用場景

資料庫DB4AI功能的實作,即在資料庫內實作AI演算法,以更好的支撐大資料的快速分析和計算,目前openGauss的DB4AI能力通過DeepSQL特性來呈現,這里提供了一整套基于SQL的機器學習、資料挖掘以及統計學的演算法,用戶可以直接使用SQL陳述句進行機器學習作業,DeepSQL能夠抽象出端到端的、從資料到模型的資料研發程序,配合底層的計算引擎及資料庫自動優化,讓具備基礎SQL知識的用戶即可完成大部分的機器學習模型訓練及預測任務,整個分析和處理都運行在資料庫引擎中,用戶可以直接分析和處理資料庫內的資料,不需要在資料庫和其他平臺之間進行資料傳遞,避免在多個環境之間進行不必要的資料移動,并且整合了碎片化的資料開發技術堆疊,

現有技術

如今,學術界與工業界在DB4AI這個方向已經了取得了許多成果,很多傳統的商業關系資料庫都已經支持了DB4AI能力,通過內置AI組件適配資料庫內的資料處理和環境,可以對資料庫存盤的資料進行處理,最大程度地減少資料移動的花費,同時,很多云資料庫、云計算資料分析平臺也都具備DB4AI能力,同時還可能具備Python、R語言等介面,便于資料分析人員快速入門,
在DB4AI領域,同樣具備很出色的開源軟體,例如Apache頂級開源專案MADlib,它兼容PostgreSQL資料庫,很多基于PostgreSQL資料庫原始碼基線進行開發的資料庫也可以很容易進行適配,MADlib可以為結構化和非結構化資料提供統計和機器學習的方法,并利用聚集函式實作在分布式資料庫上的并行化計算,MADlib支持多種機器學習、資料挖掘演算法,例如回歸、分類、聚類、統計、圖演算法等,累計支持的演算法達到70多個,在目前發布的1.17版本中MADlib支持深度學習,MADlib使用類SQL語法作為對外介面,通過創建UDF(user-defined function,用戶自定義函式)的方式將AI任務集成到資料庫中,
當前openGauss的DB4AI模塊,兼容開源的MADlib,在原始MADlib開源軟體的基礎上進行了互相適配和增強,性能相比在PostgreSQL資料庫上運行的MADlib性能更優,同時,openGauss基于MADlib框架,實作了其他工業級的、常用的演算法,例如XGBoost、Prophet、GBDT以及推薦系統等,與此同時,openGauss還具備原生的AI執行計劃與執行算子,該部分特性會在后續版本中開源,因此,本章內容主要介紹openGauss是如何兼容MADlib的,

關鍵原始碼決議

1. MADLib的專案結構

MADlib的檔案結構及說明如表8-16所示,MADlib的代碼可通過其官方網站獲取:https://madlib.apache.org/,

表8-16 MADlib的主要檔案結構

檔案結構

說明

cmake

-

Cmake相關檔案

/array_ops

陣列array操作模塊

/kmeans

Kmeans相關模塊

/sketch

詞頻統計處理相關模塊

/stemmer

詞干處理相關模塊

/svec

稀疏矩陣相關模塊

/svec_util

稀疏矩陣依賴模塊

/utils

其他公共模塊

src/bin

-

工具模塊,用于安裝、卸載、部署等

src/bin/madpack

-

資料庫互動模塊

src/dbal

-

詞干處理相關模塊

src/libstemmer

-

工具依賴檔案

src/madpack

-

里面包含公共的模塊

src/modules

-

關聯規則演算法

/assoc_rules

包括凸演算法的實作

/convex

包括條件隨機場演算法

/crf

彈性網路演算法

/elastic_net

廣義線性模型

/glm

隱狄利克雷分配

/lda

線性代數操作

/linalg

線性系統模塊

/linear_systems

概率模塊

/prob

決策樹和隨機森林

/recursive_partitioning

回歸演算法

/regress

采樣模塊

/sample

數理統計類模塊

/stats

時間序列

/utilities

包含pg,gaussdb平臺相關介面

src/ports

-

介面,鏈接db

src/ports/postgres

-

針對pg系,相關演算法

/dbconnector

關聯規則演算法

/modules

貝葉斯演算法

/modules/bayes

共軛梯度法

/modules/conjugate_gradient

包括多層感知機

/modules/convex

條件隨機場

/modules/crf

彈性網路

/modules/elastic_net

Prophet時序預測

/modules/gbdt

Gdbt演算法

/modules/glm

廣義線性模型

/modules/graph

圖模型

/modules/kmeans

Kmeans演算法

/modules/knn

Knn演算法

/modules/lda

隱狄利克雷分配

/modules/linalg

線性代數操作

/modules/linear_systems

線性系統模塊

/modules/pca

PCA降維

/modules/prob

概率模塊

/modules/recursive_partitioning

決策樹和隨機森林

/modules/sample

回歸演算法

/modules/stats

采樣模塊

/modules/summary

數理統計類模塊

/modules/svm

描述性統計的匯總函式

/modules/tsa

Svm演算法

/modules/validation

時間序列

/modules/xgboost_gs

交叉驗證

src/utils

-

Xgboost演算法

2. MADlib在openGauss上的執行流程

用戶通過呼叫UDF即可進行模型的訓練和預測,相關的結果會保存在表中,存盤在資料庫上,以訓練程序為例,MADlib在openGauss上執行的整體流程如圖8-22所示,
在這里插入圖片描述

圖8-22 MADlib在openGauss上訓練模型的流程圖

基于MADlib框架的擴展

前文展示了MADlib各個模塊的功能和作用,從結構上看,用戶可以針對自己的演算法進行擴展,前文中提到的XGBoost、GBDT和Prophet三個演算法是我們在原來基礎上擴展的演算法,本小節將以自研的GBDT模塊為例,介紹基于MADlib框架的擴展,

GBDT檔案結構如表8-17所示,

表8-17 GBDT演算法的主要檔案結構

檔案結構

說明

gbdt/gbdt.py_in

python代碼

gbdt/gbdt.sql_in

存盤程序代碼

gbdt/test/gbdt.sql

測驗代碼

在sql_in檔案中,定義上層SQL-like介面,使用PL/pgSQL或者PL/python實作,
在SQL層中定義UDF函式,下述代碼實作了類似多載的功能,

CREATE OR REPLACE FUNCTION MADLIB_SCHEMA.gbdt_train(
    training_table_name         TEXT,
    output_table_name           TEXT,
    id_col_name                 TEXT,
    dependent_variable          TEXT,
    list_of_features            TEXT,
    list_of_features_to_exclude TEXT,
    weights                     TEXT
)
RETURNS VOID AS $$
    SELECT MADLIB_SCHEMA.gbdt_train($1, $2, $3, $4, $5, $6, $7, 30::INTEGER);
$$ LANGUAGE sql VOLATILE;

CREATE OR REPLACE FUNCTION MADLIB_SCHEMA.gbdt_train(
    training_table_name         TEXT,
    output_table_name           TEXT,
    id_col_name                 TEXT,
    dependent_variable          TEXT,
    list_of_features            TEXT,
    list_of_features_to_exclude TEXT
)
RETURNS VOID AS $$
    SELECT MADLIB_SCHEMA.gbdt_train($1, $2, $3, $4, $5, $6, NULL::TEXT);
$$ LANGUAGE sql VOLATILE;

CREATE OR REPLACE FUNCTION MADLIB_SCHEMA.gbdt_train(
    training_table_name         TEXT,
    output_table_name           TEXT,
    id_col_name                 TEXT,
    dependent_variable          TEXT,
    list_of_features            TEXT
)
RETURNS VOID AS $$
    SELECT MADLIB_SCHEMA.gbdt_train($1, $2, $3, $4, $5, NULL::TEXT);
$$ LANGUAGE sql VOLATILE;

其中,輸入表、輸出表、特征等必備資訊需要用戶指定,其他引數提供預設的引數,比如權重weights,如果用戶沒有指定自定義引數,程式會用默認的引數進行運算,
在SQL層定義PL/python介面,代碼如下:

CREATE OR REPLACE FUNCTION MADLIB_SCHEMA.gbdt_train(
    training_table_name         TEXT,
    output_table_name           TEXT,
    id_col_name                 TEXT,
    dependent_variable          TEXT,
    list_of_features            TEXT,
    list_of_features_to_exclude TEXT,
    weights                     TEXT,
    num_trees                   INTEGER,
    num_random_features         INTEGER,
    max_tree_depth              INTEGER,
    min_split                   INTEGER,
    min_bucket                  INTEGER,
    num_bins                    INTEGER,
    null_handling_params        TEXT,
    is_classification           BOOLEAN,
    predict_dt_prob             TEXT,
    learning_rate               DOUBLE PRECISION,
    verbose                     BOOLEAN,
    sample_ratio                DOUBLE PRECISION
)
RETURNS VOID AS $$
PythonFunction(gbdt, gbdt, gbdt_fit)
$$ LANGUAGE plpythonu VOLATILE;

PL/pgSQL或者SQL函式最侄訓呼叫到一個PL/python函式,
“PythonFunction(gbdt, gbdt, gbdt_fit)”是固定的用法,這也是一個封裝的m4宏,會在編譯安裝的時候,會進行宏替換,
PythonFunction中,第一個引數是檔案夾名,第二個引數是檔案名,第三個引數是函式名,PythonFunction宏會被替換為“from gdbt.gdbt import gbdt_fit”陳述句,所以要保證檔案路徑和函式正確,
在python層中,實作訓練函式,代碼如下:

def gbdt_fit(schema_madlib,training_table_name, output_table_name,
        id_col_name, dependent_variable, list_of_features,
        list_of_features_to_exclude, weights,
        num_trees, num_random_features,
        max_tree_depth, min_split, min_bucket, num_bins,
        null_handling_params, is_classification,
        predict_dt_prob = None, learning_rate = None, 
        verbose=False, **kwargs):
     …
    plpy.execute("""ALTER TABLE {training_table_name} DROP COLUMN IF EXISTS gradient CASCADE
                """.format(training_table_name=training_table_name))
                            
    create_summary_table(output_table_name, null_proxy, bins['cat_features'], 
                        bins['con_features'], learning_rate, is_classification, predict_dt_prob, 
                        num_trees, training_table_name)

在python層實作預測函式,代碼如下:

def gbdt_predict(schema_madlib, test_table_name, model_table_name, output_table_name, id_col_name, **kwargs):

    num_tree = plpy.execute("""SELECT COUNT(*) AS count FROM {model_table_name}""".format(**locals()))[0]['count']
    if num_tree == 0:
        plpy.error("The GBDT-method has no trees")
    

    elements = plpy.execute("""SELECT * FROM {model_table_name}_summary""".format(**locals()))[0]
…

在py_in檔案中,定義相應的業務代碼,用python實作相應處理邏輯,
在安裝階段,sql_in和py_in會被GNU m4決議為正常的python和sql檔案,這里需要指出的是,當前MADlib框架只支持python2版本,因此,上述代碼實作也是基于python2完成的,

MADlib在openGauss上的使用示例

這里以通過支持向量機演算法進行房價分類為例,演示具體的使用方法,
(1) 資料集準備,代碼如下:

DROP TABLE IF EXISTS houses;
CREATE TABLE houses (id INT, tax INT, bedroom INT, bath FLOAT, price INT,  size INT, lot INT);
INSERT INTO houses VALUES
(1 ,  590 ,       2 ,    1 ,  50000 ,  770 , 22100),
(2 , 1050 ,       3 ,    2 ,  85000 , 1410 , 12000),
(3 ,   20 ,       3 ,    1 ,  22500 , 1060 ,  3500),
 …
(12 , 1620 ,       3 ,    2 , 118600 , 1250 , 20000),
(13 , 3100 ,       3 ,    2 , 140000 , 1760 , 38000),
(14 , 2070 ,       2 ,    3 , 148000 , 1550 , 14000),
(15 ,  650 ,       3 ,  1.5 ,  65000 , 1450 , 12000);

(2) 模型訓練
① 訓練前配置相應schema和兼容性引數,代碼如下:

SET search_path="$user",public,madlib;
SET behavior_compat_options = 'bind_procedure_searchpath';

② 使用默認的引數進行訓練,分類的條件為‘price < 100000’,SQL陳述句如下:

DROP TABLE IF EXISTS houses_svm, houses_svm_summary; 
SELECT madlib.svm_classification('public.houses','public.houses_svm','price < 100000','ARRAY[1, tax, bath, size]');

(3) 查看模型,代碼如下:

\x on
SELECT * FROM houses_svm;
\x off

結果如下:

-[ RECORD 1 ]------+-----------------------------------------------------------------
coef               | {.113989576847,-.00226133300602,-.0676303607996,.00179440841072}
loss               | .614496714256667
norm_of_gradient   | 108.171180769224
num_iterations     | 100
num_rows_processed | 15
num_rows_skipped   | 0
dep_var_mapping    | {f,t}

(4) 進行預測,代碼如下:

DROP TABLE IF EXISTS houses_pred; 
SELECT madlib.svm_predict('public.houses_svm','public.houses','id','public.houses_pred');

(5) 查看預測結果,代碼如下:

SELECT *, price < 100000 AS actual FROM houses JOIN houses_pred USING (id) ORDER BY id;

結果如下:

id | tax  | bedroom | bath | price  | size |  lot  | prediction | decision_function | actual
----+------+---------+------+--------+------+-------+------------+-------------------+--------
  1 |  590 |       2 |    1 |  50000 |  770 | 22100 | t          |      .09386721875 | t
  2 | 1050 |       3 |    2 |  85000 | 1410 | 12000 | t          |     .134445058042 | t
 …
 14 | 2070 |       2 |    3 | 148000 | 1550 | 14000 | f          |  -1.9885277913972 | f
 15 |  650 |       3 |  1.5 |  65000 | 1450 | 12000 | t          |   1.1445697772786 | t
(15 rows

查看誤分率,代碼如下:

SELECT COUNT(*) FROM houses_pred JOIN houses USING (id) WHERE houses_pred.prediction != (houses.price < 100000);

結果如下:

count
-------
     3
(1 row)

(6) 使用svm其他核進行訓練,代碼如下:

DROP TABLE IF EXISTS houses_svm_gaussian, houses_svm_gaussian_summary, houses_svm_gaussian_random; 
SELECT madlib.svm_classification( 'public.houses','public.houses_svm_gaussian','price < 100000','ARRAY[1, tax, bath, size]','gaussian','n_components=10', '', 'init_stepsize=1, max_iter=200' );

進行預測,并查看訓練結果,

DROP TABLE IF EXISTS houses_pred_gaussian; 
SELECT madlib.svm_predict('public.houses_svm_gaussian','public.houses','id', 'public.houses_pred_gaussian');
SELECT COUNT(*) FROM houses_pred_gaussian JOIN houses USING (id) WHERE houses_pred_gaussian.prediction != (houses.price < 100000);

結果如下:

count 
-------+    
0 
(1 row)

(7) 其他引數
除了指定不同的核方法外,還可以指定迭代次數、初始引數,比如init_stepsize,max_iter,class_weight等,

演進路線

openGauss當前通過兼容開源的Apache MADlib機器學習庫來具備機器學習能力,通過對原有MADlib框架的適配,openGauss實作了多種自定義的工程化演算法擴展,
除兼容業界標桿PostgreSQL系的Apache MADlib來獲得它的業務生態外,openGauss也在自研原生的DB4AI引擎,并支持端到端的全流程AI能力,這包括模型管理、超引數優化、原生的SQL-like語法、資料庫原生的AI算子與執行計劃等,性能相比MADlib具有5倍以上的提升,該功能將在后續逐步開源,

8.8 小結

本章中,介紹了openGauss團隊在AI與資料庫結合中的探索,并重點介紹了AI4DB中的引數自調優、索引推薦、例外檢測、查詢時間預測、慢SQL發現等特性,以及openGauss的DB4AI功能,無論從哪個方面講,AI與資料庫的結合遠不止于此,此處介紹的這些功能也僅是一個開端,在openGauss的AI功能上還有很多事情要做、還有很多路要走,包括AI與優化器的進一步結合;打造全流程的AI自治能力,實作全場景的故障發現與自動修復;利用AI改造資料庫內的演算法與邏輯等都是演進的方向,
雖然AI與資料庫結合已經取得了長遠的進步,但是還面臨著如下的挑戰,
(1) 算力問題:額外的AI計算產生的算力代價如何解決?會不會導致性能下降,
(2) 演算法問題:使用AI演算法與資料庫結合是否會帶來顯著的收益?演算法額外開銷是否很大?演算法能否泛化,適用到普適場景中?選擇什么樣的演算法更能解決實際問題?
(3) 資料問題:如何安全的提取和存盤AI模型訓練所需要的資料,如何面對資料冷熱分類和加載啟動問題?
上述問題在很大程度上是一個權衡問題,既要充分利用AI創造的靈感,又要充分繼承和發揚資料庫現有的理論與實踐,這也是openGauss團隊不斷探索的方向,

感謝大家學習第8章 AI技術中“8.7 DeepSQL、8.8 小結”的精彩內容,下一篇我們開啟“第9章 安全管理原始碼決議”的相關內容的介紹,
敬請期待,

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

標籤:python

上一篇:看菜雞如何搞定50塊錢1條的視頻

下一篇:數字影像處理基本運算(四)——幾何運算

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