主頁 > 資料庫 > 淺談函式式編程

淺談函式式編程

2020-09-15 00:45:53 資料庫

函式式編程(Functional Programming)是一種編程風格,它是相對于指令式編程風格而言的,常見的面向物件編程就是指令式編程風格,

指令式編程是面向計算機硬體的抽象,有變數(對應著存盤單元),賦值陳述句(獲取、存盤指令),運算式(記憶體參考和算術運算)和控制陳述句(跳轉陳述句),

而函式式編程是面向數學的抽象,將計算描述為一種運算式求值,這里的函式實際就是數學中的函式,即自變數到因變數的映射,也就是說,一個函式的值僅決定于函式引數的值,不依賴其他狀態,

函式式編程是一種抽象程度很高的編程范式,純粹的函式式編程語言撰寫的函式沒有變數,因此,任意一個函式,只要輸入是確定的,輸出就是確定的,這種純函式我們稱之為沒有副作用,而允許使用變數的程式設計語言,由于函式內部的變數狀態不確定,同樣的輸入,可能得到不同的輸出,因此,這種函式是有副作用的,

在函式式語言當中,函式作為一等公民,可以在任何地方定義,在函式內或函式外,可以作為函式的引數或回傳值,可以對函式進行組合,也可以將函式賦值給變數,嚴格意義上的函式式編程意味著不適用可變的變數,賦值,回圈和其他命令式控制結構進行編程,

函式式編程風格帶來的好處是:

  1. 函式式編程使用不可變物件作為變數,不會修改變數的值,而是回傳一個新的值,如此這樣,更容易理清頭緒,使得單元測驗和除錯更加容易;
  2. 可以很自由地傳遞不可變物件,但對于可變物件來說,傳遞給其他代碼之前,需要先建造一個以防萬一的副本;
  3. 一旦不可變物件完成構造以后,就不會有執行緒因為并發訪問而破壞物件內部狀態,因為根本沒有執行緒可以改變不可變物件的狀態;
  4. 不可變物件讓哈希表鍵值更安全,所以哈希表鍵要求必須是不可變物件,否則使用可變物件,如果物件狀態發生變化,那么在哈希表中就找不到這個物件了;

具體到編程語言,Scala(靜態語言)和Python(動態語言)都能比較的支持函式式編程風格,但是它們都不是純函式式的,也就是說它們同時支持指令式風格和函式式風格,而Java基本是指令式風格,但自從Java8引入lambda運算式以后也開始部分支持函式式風格,函式式編程最典型的是諸如map, flatMap, reduce, filter等函式,它們的特點是支持某個函式作為上面這些函式的引數,

下面分別以Java、Scala和Python舉例函式式編程,其中Java對函式式編程只是間接的支持(通過函式式介面),支持度比較有限,而Scala和Python就對函式式編程支持的比較好,

Java函式式編程舉例:

 1 package lxy.java.fp;
 2 
 3 import java.util.*;
 4 import java.util.function.*;
 5 
 6 
 7 public class FPDemo {
 8     //定義泛型方法,用以根據第二個引數指定的條件從第一個引數指定的集合中過濾部分元素,并回傳過濾后的結果,這里的第二個引數是一個函式式介面,
 9     public static <T> List <T> filter(List <T> list, Predicate <T> p) {
10         List <T> results = new ArrayList <>();
11         for (T s : list) {
12             if (p.test(s)) {
13                 results.add(s);
14             }
15         }
16         return results;
17     }
18 
19     public static void main(String[] args) {
20         List <String> myList = Arrays.asList("Hello", "Java", "Python", "Scala");
21 
22         //通過匿名類的方式
23         List <String> results = filter(myList, new Predicate <String>() {
24             public boolean test(String t) {
25                 return t.length() >= 5;
26             }
27         });
28         System.out.println("through anonymous class:");
29         System.out.println("strings with length more than 5:");
30         for (String result : results) {
31             System.out.println(result);
32         }
33 
34         //行為引數化,通過匿名函式(即lambda運算式)方式,
35         System.out.println("through lambda expression:");
36         System.out.println("strings with length more than 5:");
37         List <String> results2 = filter(myList, s -> s.length() >= 5);
38         results2.forEach(s -> System.out.println(s));
39 
40         //很容易地將過濾條件由字串長度大于等于5改為字串以字母a結尾,
41         // 這就是行為引數化,即將具體的邏輯(即行為或者函式)引數化,使得filter函式更加抽象,提高了代碼復用度
42         //否則需要寫2個filter函式,一個過濾出長度大于等于5的字串,另一個過濾出以字符a結尾的字串
43         System.out.println("strings ends with character 'a'");
44         List <String> results3 = filter(myList, s -> s.endsWith("a"));
45         results3.forEach(System.out::println);
46 
47         //Java流中的filter函式和map函式,注意這里的filter是Java庫函式,和前面自定義的filter函式不一樣
48         System.out.println("strings with length more than 5 and its length:");
49         myList.parallelStream().filter(s -> s.length() >= 5).map(s -> "(" + s + ", " + s.length() + ")")
50                 .forEach(System.out::println);
51 
52         //高階函式
53         Function <Integer, Integer> f = (Integer x) -> x + 1;
54         Function <Integer, Integer> g = (Integer x) -> x * x;
55         Function <Integer, Integer> h = f.andThen(g);
56         Function <Integer, Integer> r = f.compose(g);
57 
58         System.out.println("higher-order function:");
59         System.out.println("h(2)=g(f(2))=" + h.apply(2));
60         System.out.println("r(2)=f(g(2))=" + r.apply(2));
61 
62     }
63 }

 

Scala函式式編程舉例:

 1 package lxy.scala.fp
 2 
 3 object FPDemo {
 4     //定義泛型方法,用以根據第二個引數指定的條件從第一個引數指定的串列中過濾部分元素,并回傳過濾后的結果,結果型別仍然是List,
 5     //這里的第二個引數是一個函式, 該函式輸入引數型別為T,回傳值型別為Boolean
 6     def filter[T](list: List[T], f: T => Boolean) =
 7         for {e <- list if f(e) == true} yield e
 8 
 9     //高階函式,該函式定義為g(f(x)),其中函式f和g都是作為引數在呼叫該高階函式時指定的
10     def highOrderFunction1(x: Int, f: Int => Int, g: Int => Int) = g(f(x))
11 
12     //定義嵌套函式,針對每個引數,外層函式都會回傳一個函式,即內層函式
13     //這里factor是自由變數,number是系結變數,
14     //閉包是一個函式,回傳值依賴于宣告在函式外部的一個或多個變數
15     //函式multiplier回傳的函式就是閉包,factor就是外部的變數,也叫自由變數,number是系結變數(形式引數)
16     def multiplier(factor: Int): Int => Int = {
17         def multiplyByFactor(number: Int) = factor * number
18 
19         return multiplyByFactor
20     }
21 
22     //柯里化函式,型別是(Int)(Int) => Int
23     def multiplier2(factor: Int)(number: Int) = factor * number
24 
25     //這個函式實際跟multiplier效果是一樣的,每傳入一個引數factor,都會回傳一個函式
26     //閉包是一個函式,回傳值依賴于宣告在函式外部的一個或多個變數
27     //函式multiplier3回傳的函式就是閉包,factor就是外部的變數,也叫自由變數,number是系結變數(形式引數)
28     def multiplier3(factor: Int) = multiplier2(factor) _
29 
30     def main(args: Array[String]): Unit = {
31         val myList = List("Hello", "Java", "Python", "Scala")
32         println("strings with length more than 5")
33         filter(myList, (s: String) => s.length >= 5).foreach(s => println(s))
34 
35         println("strings ends with character 'a'")
36         filter(myList, (s: String) => s.endsWith("a")).foreach(println)
37 
38         println("strings with length more than 5 and its length:")
39         //這里的filter不是自定義函式filter,而是庫函式,回傳長度大于等于5的字串以及對應的長度
40         myList.filter(_.length >= 5).map(s => (s, s.length)).foreach(println)
41 
42 
43         val result = highOrderFunction1(2, (x: Int) => x + 1, (x: Int) => x * x)
44         println("f(x)=x+1, g(x)=x*x, g(f(2))=" + result)
45 
46 
47         println("multiplier(2)=" + multiplier(2))
48         println("multiplier(2)(3)=" + multiplier(2)(3))
49         val double = multiplier(2)
50         println("double(3)=" + double(3))
51 
52         println("multiplier3(3)=" + multiplier3(3))
53         println("multiplier3(3)(4)=" + multiplier3(3)(4))
54         val triple = multiplier3(3)
55         println("triple(4)=" + triple(4))
56 
57     }
58 }

 

Python函式式編程舉例:

 1 #!/usr/bin/env python3
 2 # -*- coding: utf-8 -*-
 3 
 4 if __name__ == "__main__":
 5     """
 6         Usage: ./fp_demo.py
 7     """
 8 
 9     # 定義函式filter,第一個引數是串列,第二個引數是函式
10     def filter(list, f):
11         return [e for e in list if f(e) == True]
12 
13     # python中沒有foreach函式,自己定義一個,其中第一個引數是函式,第二個引數是迭代器(串列)
14     def foreach(f, iterator):
15         for item in iterator:
16             f(item)
17 
18     myList = ["Hello", "Java", "Python", "Scala"]
19     resultList = filter(myList, lambda e: len(e) >= 5)
20     print("strings with length more than 5", sep="\n")
21     foreach(lambda e: print(e, sep="\n"), resultList)
22 
23     resultList2 = filter(myList, lambda e: e.endswith("a"))
24     print("strings ends with character 'a'", sep="\n")
25     foreach(lambda e: print(e, sep="\n"), resultList2)
26 
27     # 這里的map函式是python內置的
28     print("strings with length more than 5 and its length:", sep="\n")
29     foreach(lambda e: print(e, sep="\n"), map(lambda e: (e, len(e)), filter(myList, lambda e: len(e) >= 5)))
30 
31     # 高階函式,該函式定義為g(f(x)),其中函式f和g都是作為引數在呼叫該高階函式時指定的
32     def highOrderFunction1(x, f, g):
33         return g(f(x))
34 
35     # 該函式在下面對highOrderFunction1函式的呼叫中被當做引數傳入
36     def f(x):
37         return x + 1
38 
39     # 第二個引數傳入上面定義的f函式,作為第三個引數的的函式采用的是匿名函式
40     result = highOrderFunction1(2, f, g=lambda x: x * x)
41     print("f(x)=x+1, g(x)=x*x, g(f(2))=%d" % result, sep="\n")
42 
43     # 定義嵌套函式,針對每個引數,外層函式都會回傳一個函式,即內層函式
44     # 這里factor是自由變數,number是系結變數,
45     # 閉包是一個函式,回傳值依賴于宣告在函式外部的一個或多個變數
46     # 函式multiplier回傳的函式就是閉包,factor就是外部的變數,也叫自由變數,number是系結變數(形式引數)
47     def multiplier(factor):
48         def multiplyByFactor(number):
49             return factor * number
50         return multiplyByFactor
51 
52 
53     print("multiplier(2)(3)=%s" % multiplier(2)(3))
54     # double是一個函式,它將輸入引數乘以2倍以后回傳
55     double = multiplier(2)
56     print("double(3)=%s" % double(3))
57 
58     print("multiplier(3)(4)=%s" % multiplier(3)(4))
59     # triple是一個函式,它將輸入引數乘以3倍以后回傳
60     triple = multiplier(3)
61     print("triple(4)=%s" % triple(4))
62 
63     # 第三個引數f是函式
64     def add(x, y, f):
65         return f(x) + f(y)
66 
67     print("2 ^ 2 + 3 ^2 = %s" % add(2, 3, lambda x: x * x))
68     print("(2 + 1) + (3 + 1) = %s" % add(2, 3, f))

 

最后來看一個數學題目,已知a<=b, ab都是整數,求下面三個公式的值,

 可以看到這三個公式分別是求a~b的和,a~b的平方和,a~b各自的階乘的和,可以看到三個公式是類似的,都是求和,只不過分別是對自身求和,對自身的平方求和以及對自身的階乘求和,也就是說這里有3個計算邏輯,需要對這3個計算邏輯計算出來的數求和,如果是指令式編程風格,就只能寫三個函式來解決問題,但是如果采用函式式編程風格,就可以只寫一個通用的求和函式來解決該問題,因為可以將這3個計算邏輯(函式)作為引數傳給之前的通用求和函式,下面分別用Java,ScalaPython來解決該問題,

Java代碼

 1 package lxy.java.fp;
 2 
 3 import java.util.function.*;
 4 
 5 
 6 public class Sum4Integers {
 7     //通用求和函式,其中f是一個函式式介面,它接收一個整型引數并回傳一個整型數值
 8     //采用遞回計算方法
 9     private static int sum(Function<Integer, Integer> f, int a, int b) {
10         if (a > b)
11             return 0;
12         else
13             return f.apply(a) + sum(f, a + 1, b);
14     }
15 
16     //求階乘函式,采用遞回演算法,較復雜,不能作為匿名函式傳入上面的通用求和引數,因此需要預先定義
17     private static int factor(int x) {
18         if (x == 0)
19             return 1;
20         else
21             return x * factor(x - 1);
22     }
23 
24     //求公式一函式,即求a~b的和
25     //作為引數的函式就是回傳變數自身,較簡單,采用匿名函式
26     static int sumInts(int a, int b) {
27         return sum(x -> x, a, b);
28     }
29 
30     //求公式二函式,即求a^2 ~ b^2的和
31     //作為引數的函式就是回傳變數的平方,較簡單,采用匿名函式
32     static int sumSquares(int a, int b) {
33         return sum(x -> x * x, a, b);
34     }
35 
36     //求公式三函式,即求a! ~ b!的和
37     //作為引數的函式就是求變數的階乘,較復雜(本身是遞回函式),采用定義好的函式factor
38     static int sumFactors(int a, int b) {
39         return sum(Sum4Integers::factor, a, b);
40     }
41 
42     public static void main(String[] args) {
43         System.out.println("1+2+3+4+5=" + sumInts(1, 5));
44         System.out.println("1^2+2^2+3^2+4^2+5^2=" + sumSquares(1, 5));
45         System.out.println("1!+2!+3!+4!+5!=" + sumFactors(1, 5));
46     }
47 
48 }

 

Scala代碼

 1 package lxy.scala.fp
 2 
 3 
 4 object Sum4Integers {
 5     //通用求和函式
 6     //采用遞回計算方法
 7     private def sum(f: Int => Int, a: Int, b: Int): Int = if (a > b) 0 else f(a) + sum(f, a + 1, b)
 8 
 9     //求階乘函式,采用遞回演算法,較復雜,不能作為匿名函式傳入上面的通用求和引數,因此需要預先定義
10     private def factor(x: Int): Int = if (x == 0) 1 else x * factor(x - 1)
11 
12     //求公式一函式,即求a~b的和
13     //作為引數的函式就是回傳變數自身,較簡單,采用匿名函式
14     def sumInts(a: Int, b: Int) = sum(x => x, a, b)
15 
16     //求公式二函式,即求a^2 ~ b^2的和
17     //作為引數的函式就是回傳變數的平方,較簡單,采用匿名函式
18     def sumSquares(a: Int, b: Int) = sum(x => x * x, a, b)
19 
20     //求公式三函式,即求a! ~ b!的和
21     //作為引數的函式就是求變數的階乘,較復雜(本身是遞回函式),采用定義好的函式factor
22     def sumFactors(a: Int, b: Int) = sum(factor, a, b)
23 
24     def main(args: Array[String]): Unit = {
25         println("1+2+3+4+5=" + sumInts(1, 5))
26         println("1^2+2^2+3^2+4^2+5^2=" + sumSquares(1, 5))
27         println("1!+2!+3!+4!+5!=" + sumFactors(1, 5))
28     }
29 
30 }

 

Python代碼

 1 #!/usr/bin/env python3
 2 # -*- coding: utf-8 -*-
 3 
 4 if __name__ == "__main__":
 5     """
 6         Usage: ./sum_integers.py
 7     """
 8 
 9     # 通用求和函式,采用遞回計算方法
10     def sum(f, a, b):
11         if a > b:
12             return 0
13         else:
14             return f(a) + sum(f, a + 1, b)
15 
16     # 求階乘函式,采用遞回演算法,較復雜,不能作為匿名函式傳入上面的通用求和引數,因此需要預先定義
17     def factor(x):
18         if x == 0:
19             return 1
20         else:
21             return x * factor(x - 1)
22 
23     # 求公式一函式,即求a~b的和
24     # 作為sum函式的第一個引數的函式就是回傳變數自身,較簡單,采用匿名函式
25     def sumInts(a, b):
26         return sum(lambda x: x, a, b)
27 
28     # 求公式二函式,即求a^2 ~ b^2的和
29     # 作為sum函式的第一個引數的函式就是回傳變數的平方,較簡單,采用匿名函式
30     def sumSquares(a, b):
31         return sum(lambda x: x * x, a, b)
32 
33     # 求公式三函式,即求a! ~ b!的和
34     # 作為sum函式的第一個引數的函式就是求變數的階乘,較復雜(本身是遞回函式),采用定義好的函式factor
35     def sumFactors(a, b):
36         return sum(factor, a, b)
37 
38     print("1+2+3+4+5=%d" % sumInts(1, 5))
39     print("1^2+2^2+3^2+4^2+5^2=%d" % sumSquares(1, 5))
40     print("1!+2!+3!+4!+5!=%d" % sumFactors(1, 5))

 

從上面解決同一個問題的代碼量比較來看,Scala和Python比較短,而Java比較長,而且Java對函式式編程的支持目前還比較有限,因此函式式編程建議采用Scala或者Python,

 

 

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

標籤:大數據

上一篇:spark-3.0 application 調度演算法決議

下一篇:根據資料視窗中的值,打開這個網頁!

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

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more