主頁 > 軟體設計 > orangepi 4B利用python3使用snowboy實作語音喚醒以及使用騰訊AI api實作語音識別、回復以及合成

orangepi 4B利用python3使用snowboy實作語音喚醒以及使用騰訊AI api實作語音識別、回復以及合成

2020-10-01 21:53:23 軟體設計

orangepi 4B利用python3使用snowboy實作語音喚醒以及使用騰訊AI api實作語音識別、回復以及合成

  • 一個月來經歷無數個坑,終于完成教程,整理不易,轉載請注明出處,謝謝
  • 準備作業
    • 基本知識與儲備
    • 硬體方面準備
      • 準備材料
      • 鏡像下載地址
      • 鏡像安裝方法
    • 軟體方面準備
      • 騰訊AI開放平臺注冊開發者
      • 仔細查看開發檔案以及完成應用創建
  • 正式開始操作
    • 登錄以及環境配置
      • 切換中文環境以及安裝中文輸入法
      • 時區設定與中文支持
    • python3安裝及snowboy編譯
      • 安裝python3以及pip3
      • 安裝portaudio、pyaudio以及其他python3的支持包(重點,不安裝無法使用pyaudio,更無法使用語音識別)
      • 安裝swig以及ATLAS依賴
      • 獲取snowboySDK以及snowboy的編譯(注:4B需要修改的地方是重點否則無法完成編譯)
    • 利用騰訊AI api完成語音識別,回復,以及語音合成
      • 用到的python模塊以及引數設定
      • 用來生成需要位數的隨機字符
      • 介面鑒權撰寫
      • 利用wave模塊保存錄音
      • 使用pyaudio錄音
      • 使用pyaudio播放
      • 語音識別
      • 得到回答
      • 語音合成
    • 測驗snowboy以及修改demo
      • 測驗snowboy熱詞喚醒功能
      • 修改Demo
  • 后續延伸
    • 語音控制智能機器人
    • 語音控制家庭智能家居中心

一個月來經歷無數個坑,終于完成教程,整理不易,轉載請注明出處,謝謝

準備作業

基本知識與儲備

1.python基本語法、模塊庫的呼叫、常用模塊熟練呼叫
2.Linux環境的使用,熟悉apt,pip,git下載,python3環境配置
3.一顆能堅持下來的耐心
4.遇到問題能主動去找百度,而不是放棄

硬體方面準備

準備材料

一張16Gclass10SD卡、一個USB2.0或3.0的讀卡器、一個orangepi4B主板、一個USB麥克風(淘寶10塊還包郵那種)、一個支持AUX音響(沒有可以用耳機代替)、一個支持HDMI的顯示幕、一個鍵盤、一個滑鼠以及一個USB擴展塢
下面是我準備的SD卡以及讀卡器
在這里插入圖片描述

鏡像下載地址

我使用的是香橙派官方ubuntu-npu鏡像地址:香橙派官網.
選擇下載用戶手冊和原理圖在檔案中找到這個檔案OrangePi_4_ubuntu_bionic_desktop_linux4.4.179_npu_v1.3.tar.gz
也可以直接在這個鏈接下載: https://pan.baidu.com/s/17549ZGbNTLuJANoiJAA7JQ 提取碼: sja5
同時下載官方工具包找到Win32DiskImager以及SDFormatter或者百度自行下載
Win32DiskImagerSDFormatter

鏡像安裝方法

首先使用SDFormatter將SD卡格式化(這里請備份好自己的資料)第一步
格式化完成
接下來使用Win32DiskImager寫入鏡像到SD卡
寫入鏡像到SD卡
等待提示完成,拔出SD卡,插入opi4b卡槽插上顯示幕鍵盤滑鼠然后插上電源開機,先使用賬號為root密碼為orangepi登錄root登錄
打開LX終端
打開終端

使用install_to_emmc命令將鏡像燒錄至emmc(期間會提示輸入一次Y)

在這里插入圖片描述

提示燒錄完成執行reboot命令重啟香橙派,同時拔出SD卡
至此完成鏡像燒錄以及準備作業

軟體方面準備

騰訊AI開放平臺注冊開發者

很簡單,百度一大堆,自己也可以摸索,這里就不贅述了

仔細查看開發檔案以及完成應用創建

###################################################

正式開始操作

登錄以及環境配置

切換中文環境以及安裝中文輸入法

打開LX終端執行sudo apt-get install ttf-wqy-zenhei安裝中文字庫
執行sudo apt-get install fcitx fcitx-googlepinyin fcitx-module-cloudpinyin fcitx-sunpinyin
安裝中文輸入法
然后重啟就可以看到輸入法安裝完成(中英文切換方式為)

時區設定與中文支持

在LX終端設定上海時間
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
中文環境設定, 打開終端, 輸入以下命令
sudo dpkg-reconfigure locales
語言配置界面
然后往下找(鍵盤-按下鍵) , 在較后面, 找到 en_US.UTF-8 UTF-8,zh_CN.UTF-8 UTF-8,zh_CN.GBK GBK 如上圖所示,按空格選中, 按回車確定,
然后來到如下界面, 選擇 zh_CN.UTF-8, 確定, 按下回車鍵,
選擇中文
出現如下資訊, 配置完成,重啟系統即可,
完成

python3安裝及snowboy編譯

安裝python3以及pip3

終端執行

sudo apt-get install python3 python3-pip3

安裝portaudio、pyaudio以及其他python3的支持包(重點,不安裝無法使用pyaudio,更無法使用語音識別)

終端執行

sudo apt-get install portaudio19-dev python-all-dev python3-all-dev jackd1 portaudio19-doc jack-tools meterbridge liblo-dev
sudo apt-get install pyaudio

安裝swig以及ATLAS依賴

終端執行

sudo apt-get install swig
sudo apt-get install libatlas-base-dev

獲取snowboySDK以及snowboy的編譯(注:4B需要修改的地方是重點否則無法完成編譯)

終端執行

git clone https://github.com/Kitt-AI/snowboy.git

需要修改的地方①在snowboy/swig/Python3中的makefile
找到下圖中位置將ubuntu64替換為aarch64-ubuntu1604
修改1
地方②在snowboy/examples/Python3中的snowboydecoder.py檔案
將from * import snowboydetect 修改為import snowboydetect
在這里插入圖片描述
在snowboy/swig/Python3檔案夾打開終端執行make
至此snowboy編譯完成,

利用騰訊AI api完成語音識別,回復,以及語音合成

用到的python模塊以及引數設定

import base64
import json
import operator
import random
import time
import wave
from urllib import parse
import hashlib
import snowboydecoder
import signal
from contextlib import contextmanager
import requests
from pyaudio import PyAudio, paInt16
CHUNK = 1024  # wav檔案是由若干個CHUNK組成的,CHUNK我們就理解成資料包或者資料片段,
FORMAT = paInt16  # 表示我們使用量化位數 64位來進行錄音
CHANNELS = 1  # 代表的是聲道,1是單聲道,2是雙聲道,
RATE = 16000  # 采樣率 一秒內對聲音信號的采集次數,常用的有8kHz, 16kHz, 32kHz, 48kHz,11.025kHz, 22.05kHz, 44.1kHz,
RECORD_SECONDS = 5  # 錄制時間這里設定了5秒
app_id = '你的appid' # 從開發者平臺得到
appkey = '你的appkey ' # 從開發者平臺得到

用來生成需要位數的隨機字符

def roda(num):
    a = ''
    for i in range(0, num):
        a = a + random.choice('abcdefghijklmnopqrstuvwxyz123456789')
    return a

介面鑒權撰寫

官方解釋
用于計算簽名的引數在不同介面之間會有差異,但演算法程序固定如下4個步驟,
1…將<key, value>請求引數對按key進行字典升序排序,得到有序的引數對串列N
2.將串列N中的引數對按URL鍵值對的格式拼接成字串,得到字串T(如:key1=value1&key2=value2),URL鍵值拼接程序value部分需要URL編碼,URL編碼演算法用大寫字母,例如%E8,而不是小寫%e8
3.將應用密鑰以app_key為鍵名,組成URL鍵值拼接到字串T末尾,得到字串S(如:key1=value1&key2=value2&app_key=密鑰)
4.對字串S進行MD5運算,將得到的MD5值所有字符轉換成大寫,得到介面請求簽名
實際撰寫

def sortDict(data):
    return dict(sorted(data.items(), key=operator.itemgetter(0), reverse=False))

def getReqSign(params, appkey):
    # 1. 字典升序排序
    params1=sortDict(params)
    # 2. 拼按URL鍵值對
    str1 = parse.urlencode(params1)
    # 3. 拼接app_key
    str1 = str1 + '&' + 'app_key=' + appkey
    # 4. MD5運算并轉換大寫,回傳請求簽名
    m = hashlib.md5()
    m.update(str1.encode())
    str_md5 = m.hexdigest()
    return str_md5.upper()

利用wave模塊保存錄音

def save_wave_file(pa, filename, data):
    wf = wave.open(filename, 'wb')
    wf.setnchannels(1)
    wf.setsampwidth(pa.get_sample_size(paInt16))
    wf.setframerate(16000)
    print(type(data))
    wf.writeframes(b"".join(data))
    wf.close()

使用pyaudio錄音

def get_audio(filepath):  # 錄音實作
    print("請開始說話:")  # 提示文本
    pa = PyAudio()
    stream = pa.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK)
    print("*" * 10, "開始錄音:請在5秒內輸入語音")
    frames = []  # 定義一個串列
    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):  # 回圈,采樣率 44100 / 1024 * 5
        data = stream.read(CHUNK)  # 讀取chunk個位元組 保存到data中
        frames.append(data)  # 向串列frames中添加資料data吃
    print("*" * 10, "錄音結束\n")
    stream.stop_stream()
    stream.close()  # 關閉
    pa.terminate()  # 終結
    save_wave_file(pa, filepath, frames)

使用pyaudio播放


def play(fname):
    ding_wav = wave.open(fname, 'rb')
    ding_data = ding_wav.readframes(ding_wav.getnframes())
    with no_alsa_error():
        audio = PyAudio()
    stream_out = audio.open(
        format=audio.get_format_from_width(ding_wav.getsampwidth()),
        channels=ding_wav.getnchannels(),
        rate=ding_wav.getframerate(), input=False, output=True)
    stream_out.start_stream()
    stream_out.write(ding_data)
    time.sleep(0.2)
    stream_out.stop_stream()
    stream_out.close()
    audio.terminate()

語音識別

1.請求引數

引數名稱是否必選資料型別資料約束示例資料描述
app_idint正整數1000001應用標識(AppId)
time_stampint正整數1493468759請求時間戳(秒級)
nonce_strstring非空且長度上限32位元組fa577ce340859f9fe隨機字串
signstring非空且長度固定32位元組簽名資訊,詳見介面鑒權
format 是int正整數2語音壓縮格式編碼,定義見下文描述
speechstring語音資料的Base64編碼,非空且長度上限8MB待識別語音(時長上限15s)
rateint正整數16000語音采樣率編碼,定義見下文描述,(不傳)默認即16KHz

語音壓縮格式編碼

格式名稱格式編碼
PCM1
WAV2
AMR3
SILK4

語音采樣率編碼

采樣率編碼
8KHz8000
16KHz16000

2. 回應引數

引數名稱是否必選資料型別描述
retint回傳碼; 0表示成功,非0表示出錯
msgstring回傳資訊;ret非0時表示出錯時錯誤原因
dataobject回傳資料;ret為0時有意義
+ formatintAPI請求中的格式編碼
+ rateintAPI請求中的采樣率編碼
+ textstring語音識別結果(UTF-8編碼)

撰寫示例

def get_text():
    get_audio('ceshi.wav') # 錄音
    fwave = open('ceshi.wav', mode='rb').read() # 打開錄音檔案
    base64Wav = base64.b64encode(fwave).decode('utf8') # 進行編碼(騰訊api要求base64編碼)
    params = {'app_id': app_id,
     		  'format': '2', 
    		  'rate': '16000',  
              'speech': base64Wav,     # base64編碼的語音資料
              'time_stamp': int(time.time()),  # 時間戳
              'nonce_str': roda(10)}
    params['sign'] = getReqSign(params, appkey) # 得到介面鑒權
    # print(params)
    url = 'https://api.ai.qq.com/fcgi-bin/aai/aai_asr'
    resp = requests.post(url, params)  # post請求
    return json.loads(resp.text).get('data').get('text') #回傳識別到的文本

得到回答

1. 請求引數

引數名稱是否必選資料型別資料約束示例資料描述
app_idint正整數1000001應用標識(AppId)
time_stampint正整數1493468759請求時間戳(秒級)
nonce_strstring非空且長度上限32位元組fa577ce340859f9fe隨機字串
signstring非空且長度固定32位元組簽名資訊,詳見介面鑒權
sessionstringUTF-8編碼,非空且長度上限32位元組10000會話標識(應用內唯一)
questionstringUTF-8編碼,非空且長度上限300位元組你叫啥用戶輸入的聊天內容

2. 回應引數

引數名稱是否必選資料型別描述
retint回傳碼; 0表示成功,非0表示出錯
msgstring回傳資訊;ret非0時表示出錯時錯誤原因
dataobject回傳資料;ret為0時有意義
sessionstringUTF-8編碼,非空且長度上限32位元組
answerstringUTF-8編碼,非空

撰寫示例

def get_chat_text(text):  # 得到回答
    paramsd = {
        'app_id': app_id,
        'session': '10000',
        'question': text,    # 問題文本
        'time_stamp': int(time.time()),
        'nonce_str': roda(17),
    }
    paramsd['sign'] = getReqSign(paramsd, appkey)
    urld = 'https://api.ai.qq.com/fcgi-bin/nlp/nlp_textchat'
    respd = requests.post(urld, paramsd)
    return json.loads(respd.text).get('data').get('answer')  # 回傳回答文本

語音合成

1. 請求引數

引數名稱是否必選資料型別資料約束示例資料描述
app_idint正整數1000001應用標識(AppId)
time_stampint正整數1493468759請求時間戳(秒級)
nonce_strstring非空且長度上限32位元組fa577ce340859f9fe隨機字串
signstring非空且長度固定32位元組簽名資訊,詳見介面鑒權
speakerint正整數1語音發音人編碼,定義見下文描述
formatint正整數2合成語音格式編碼,定義見下文描述
volumeint[-10, 10]0合成語音音量,取值范圍[-10, 10],如-10表示音量相對默認值小10dB,0表示默認音量,10表示音量相對默認值大10dB
speedint[50, 200]100合成語音語速,默認100
textstringUTF-8編碼,非空且長度上限150位元組騰訊,你好!待合成文本
ahtint[-24, 24]0合成語音降低/升高半音個數,即改變音高,默認0
apcint[0, 100]58控制頻譜翹曲的程度,改變說話人的音色,默認58

語音發音人編碼

發音人編碼
普通話男聲1
靜琪女聲5
歡馨女聲6
碧萱女聲7

合成語音格式編碼

格式名稱編碼
PCM1
WAV2
MP33

2. 回應引數

引數名稱是否必選資料型別描述
retint回傳碼;
msgstring回傳資訊;ret非0時表示出錯時錯誤原因
dataobject回傳資料;ret為0時有意義
+ formatintAPI請求中的格式編碼
+ speechstring合成語音的base64編碼資料
+ md5sumstring合成語音的md5摘要(base64編碼之前)

base64解碼及寫入檔案

def ToFile(voicex, file):
    base64_data = voicex
    ori_image_data = base64.b64decode(base64_data)
    fout = open(file, 'wb')
    fout.write(ori_image_data)
    fout.close()

撰寫示例

def get_voice(text):
    test = {
        'app_id': app_id,
        'speaker': '6',
        'format': '2',
        'volume': '0',
        'speed': '100',
        'text': text,
        'aht': '0',
        'apc': '58',
        'time_stamp': int(time.time()),
        'nonce_str': roda(17),
    }
    test['sign'] = getReqSign(test, appkey)
    url2 = 'https://api.ai.qq.com/fcgi-bin/aai/aai_tts'
    resp2 = requests.post(url2, test)
    voicex=json.loads(resp2.text).get('data').get('speech')
    ToFile(str(voicex), 'audio.txt')
    ToFile(voicex, 'audio.mp3')
    return 'audio.mp3'

測驗snowboy以及修改demo

測驗snowboy熱詞喚醒功能

終端打開目錄 snowboy/examples/Python3

     cd  snowboy/examples/Python3

開始運行,喊一聲snowboy就可以聽到叮的一聲

    python3 demo.py resources/models/snowboy.umdl

修改Demo

interrupted = False

def signal_handler(signal, frame):
    global interrupted
    interrupted = True

def interrupt_callback():
    global interrupted
    return interrupted

# 回呼函式,語音識別在這里實作,修改也是在這里
def callbacks():
    global detector
    time.sleep(0.2)
    your_text=['哎,我在,你說','我來啦,我來啦,我來啦~','我是你的語音助手小貝']
    a=random.randint(1,3)
    print('小貝'+your_text[a])
    play('huda/xiaobeihuida'+ str(a) +'.wav')  # 為喚醒詞事先準備好的回答
    time.sleep(0.2)
    try:
        a = get_text()
        if a =='嗯' or '':
            continue
        print('你:'+a)
        b =get_chat_text(a)
        print('小貝:'+b)
        c = get_voice(b)
        play(c)
    except Exception:
        print('exception happened...')


@contextmanager
def no_alsa_error():
    try:
        asound = cdll.LoadLibrary('libasound.so')
        asound.snd_lib_error_set_handler(c_error_handler)
        yield
        asound.snd_lib_error_set_handler(None)
    except:
        yield
        pass


def wake_up():
    global detector
    model = 'xiaobeixiaobei.pmdl'  # 我的喚醒詞為 小貝小貝
    # 終止方法為ctrl+c
    signal.signal(signal.SIGINT, signal_handler)
    # 喚醒詞檢測函式,調整sensitivity引數可修改喚醒詞檢測的準確性
    detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)
    print('正在聆聽... 請說喚醒詞:小貝小貝')
    # main loop
    # 回呼函式 detected_callback=snowboydecoder.play_audio_file
    # 修改回呼函式可實作我們想要的功能
    detector.start(detected_callback=callbacks,  # 自定義回呼函式
                   interrupt_check=interrupt_callback,
                   sleep_time=0.03)
    # 釋放資源
    detector.terminate()
#程式入口
if __name__ == "__main__":
    wake_up()

后續延伸

修改回呼函式可以完成更多作業

語音控制智能機器人

與arduino使用uart通信可實作智能控制機器人
等待后續更新
已經更新傳送門

語音控制家庭智能家居中心

加入mqtt可以作為語音控制家庭智能家居中心
等待后續更新

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

標籤:其他

上一篇:玩轉華為云,ModelArts深度學習建模最全搭建手冊

下一篇:縱橫美國思維導圖學習

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

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more