鴻蒙5.0項目開發——接入有道大模型翻譯

鴻蒙5.0項目開發——接入有道大模型翻譯

【高心星出品】

項目效果圖

在這里插入圖片描述

項目功能

  1. 文本翻譯功能

    • 支持文本輸入和翻譯結果顯示

    • 使用有道翻譯API進行翻譯

    • 支持自動檢測語言(auto)

    • 支持雙向翻譯(源語言和目標語言可互換)

  2. 文本操作功能

    • 支持文本復制

    • 支持文本全選

    • 支持長按選擇文本

    • 支持滾動查看長文本

  3. 生詞本功能

    • 可以將翻譯結果保存到生詞本

    • 支持保存選中文本的翻譯

    • 支持保存整個翻譯結果

    • 記錄保存時間

  4. 用戶界面特點

    • 采用上下布局,上方為輸入區,下方為結果顯示區

    • 支持實時翻譯

    • 提供清晰的視覺反饋

    • 支持長按菜單操作

  5. 數據存儲

    • 使用鴻蒙系統的數據存儲能力

    • 支持生詞本的本地存儲

    • 支持歷史記錄保存

  6. 網絡功能

    • 集成有道翻譯API

    • 支持HTTP請求

    • 支持錯誤處理

    • 支持數據流式傳輸

  7. 安全特性

    • 使用API密鑰進行身份驗證

    • 支持數據加密傳輸

    • 實現簽名驗證機制

  8. 其他功能

    • 支持剪貼板操作

    • 提供操作提示(Toast提示)

    • 支持文本格式化

    • 支持多語言界面

大模型翻譯 API 簡介

大型模型翻譯:翻譯的好助手,使用此服務可以完成翻譯、潤色、擴寫等功能。API可以處理各種復雜的語言結構、詞匯和語境,提供高質量的翻譯結果。 同時,可以根據用戶的需 求和偏好進行定制化的翻譯。用戶可以通過調整參數、提供上下文信息或者進行反饋,使翻譯結果更符合個人或特 定領域的要求,從而實現更加精準、個性化的翻譯體驗。

接入有道翻譯過程

  • 首先要注冊成為有道智云的開發者并創建應用:https://ai.youdao.com/doc.s#guide,就可以拿到 應用ID應用密鑰

  • 大模型翻譯API HTTPS地址:

https://openapi.youdao.com/llm_trans
  • 請求方式:
規則描述
傳輸方式HTTPS
請求方式GET/POST
字符編碼統一使用UTF-8 編碼
請求格式表單
響應格式text/event-stream
  • 請求參數:
字段名類型含義必填備注
itext待翻譯文本True必須是UTF-8編碼,限制5000字符
prompttext提示詞False必須是UTF-8編碼,限制1200字符、400單詞
fromtext源語言True參考下方支持語言 (可設置為auto)
totext目標語言True參考下方支持語言
streamTypetext流式返回類型False參考下方 流式返回類型
appKeytext應用IDTrue可在應用管理 查看
salttext隨機字符串,可使用UUID進行生產Trueuuid (可使用uuid生成)
signtext簽名Truesha256(應用ID+input+salt+curtime+應用密鑰)
signTypetext簽名類型Truev3
curtimetext當前UTC時間戳(秒)TrueTimeStamp
handleOptiontext處理模式選項False參考下方 處理模式選項
polishOptiontext潤色選項False參考下方 潤色選項
expandOptiontext擴寫選項False參考下方 擴寫選項

簽名生成方法如下: signType=v3; sign=sha256(應用ID+input+salt+curtime+應用密鑰); 其中,input的計算方式為:input=i前10個字符 + i長度 + i后10個字符(當i長度大于20)或 input=i字符串(當i長度小于等于20);

  • 流式返回類型SSE:
event:begindata:{"requestId":"11","type":"zh-CHS2en"}event:messagedata:{"transFull":null,"transIncre":"The"}event:messagedata:{"transFull":null,"transIncre":" w"}...............event:enddata:{"requestId":"11","type":"zh-CHS2en","eventTokenUsage":{"inputToken":5,"outputToken":7,"totalToken":12}}

網絡請求工具封裝

由于大模型翻譯獲取的是增量的翻譯結果,一次應答只能獲取部分翻譯結果,所以我們發送請求的方式要用requestInStream發起流式請求,然后在 req.on(‘dataReceive’, (data) =>{})中獲取每次返回的SSE結果。

此工具封裝最復雜的就是請求參數的獲取,時間戳curtime要獲取當前系統時間的秒級結果,并且服務器會將服務器時間與發送請求的時間戳進行對比,如果差距超過15分鐘,請求就會失敗,所以要關注一下運行該段代碼設備的時間。

/*** 生成請求參數* @param q 待翻譯的文本* @returns 包含簽名等信息的請求參數對象*/
export function genparm(q: string): reqparam {q = q.trim()let salt = util.generateRandomUUID()let curtime = Math.round(new Date().getTime() / 1000) + ''let param: reqparam = {i: q,q: q,from: 'auto',to: 'auto',appKey: APPKEY,curtime: curtime,signType: 'v3',salt: salt,sign: sign(q, curtime, salt)}return param
}/*** 生成簽名* @param q 待翻譯的文本* @param curtime 當前時間戳* @param salt 隨機字符串* @returns SHA256加密后的簽名*/
function sign(q: string, curtime: string, salt: string) {let str = APPKEY + getinput(q) + salt + curtime + APPSECRETlet result: string = ''try {let mdAlgName = 'SHA256'; // 使用SHA256算法let md = cryptoFramework.createMd(mdAlgName);// 更新數據md.updateSync({ data: new Uint8Array(buffer.from(str, 'utf-8').buffer) });let mdResult = md.digestSync();// 將摘要結果轉換為十六進制字符串result = Array.from(mdResult.data).map(byte => byte.toString(16).padStart(2, '0')).join('');} catch (error) {console.error('SHA256編碼失敗:', error);}return result
}/*** 處理輸入文本* @param q 待處理的文本* @returns 處理后的文本* 如果文本長度大于20,則取前10個字符和后10個字符,中間加上長度*/
function getinput(q: string) {let len = q.lengthlet result: stringif (len <= 20) {result = q} else {let startstr = q.substring(0, 10)let endstr = q.substring(len - 10, len)result = startstr + len + endstr}return result
}/*** 發送LLM翻譯請求* @param q 待翻譯的文本* @param recievedata 接收數據的回調函數* @returns Promise<number> 請求ID*/
export function postllm(q: string, recievedata: (data: string) => void) {let req = http.createHttp()let param = genparm(q)let opt: http.HttpRequestOptions = {method: http.RequestMethod.POST,header: {'Content-Type': 'application/x-www-form-urlencoded'},extraData: `i=${param.i}&q=${param.q}&from=auto&to=auto&appKey=${param.appKey}&curtime=${param.curtime}&signType=v3&salt=${param.salt}&sign=${param.sign}`}let strs: string[] = []req.on('dataReceive', (data) => {// 處理接收到的數據let result = buffer.from(data).toString()console.log('gxxt result ', result)if (!result.endsWith('\n')) {strs.push(result.substring(result.lastIndexOf('\n') + 1))result = result.substring(0, result.lastIndexOf('\n') + 1)} else {if (strs.length > 0) {result = strs.join('') + resultstrs = []}}console.log('gxxt newresult ', result)recievedata(result)})return new Promise<number>((resolve, reject) => {req.requestInStream(BASEURL, opt).then((num) => {resolve(num)}).catch((e: Error) => {reject(e.message)})})
}

流式返回數據的處理

目前鴻蒙還沒有支持解析SSE數據的工具,需要開發者自己封裝,其實就是對于字符串的處理。鑒于SSE的結構,可以按照\n\n雙換行來切割獲取不同的事件類型,然后只處理event:message事件即可。

/*** 解析服務器返回的SSE(Server-Sent Events)數據* @param data 服務器返回的原始數據字符串* @returns 解析后的翻譯結果數組,如果發生錯誤則返回undefined*/export function getResult(data: string) {let ret: string[] = []// 檢查是否包含錯誤信息if (data.lastIndexOf('event:error') !== -1) {return}// 按事件分割數據let events = data.split('\n\n')events.forEach((item: string) => {// 處理消息事件if (item.indexOf('event:message') !== -1) {let data1 = item.split('event:message\n')data1.forEach((itemn: string) => {// 提取JSON數據并解析if (itemn.length > 1 && itemn.indexOf('{') !== -1) {let jsondata = itemn.substring(itemn.indexOf('{'), itemn.indexOf('}') + 1)let res = JSON.parse(jsondata) as resdataret.push(res.transIncre)}})}})return ret}

主界面代碼

這是一個名為"星星翻譯"的鴻蒙應用主界面,界面設計簡潔實用,主要分為三個部分:

頂部是標題欄,顯示"星星翻譯"的應用名稱,采用簡潔的白色背景設計。

中間是核心的翻譯區域,采用上下分欄布局:

  • 上方是文本輸入區,用戶可以在這里輸入需要翻譯的內容

  • 下方是翻譯結果顯示區,實時顯示翻譯結果

  • 兩個區域之間有一個翻譯按鈕,點擊即可執行翻譯操作

  • 翻譯結果支持長按選擇文本,可以進行復制、全選等操作

底部是功能操作欄,提供兩個主要功能按鈕:

  • 復制按鈕:可以將翻譯結果一鍵復制到剪貼板

  • 生詞本按鈕:可以將當前的翻譯內容保存到生詞本中,方便后續復習

/*** 星星翻譯應用主頁面* 提供文本翻譯、復制結果、生詞本記錄等功能*/
import { postllm } from '../utils/HttpUtils';
import { getResult, gettime } from '../utils/StringUtils';
import { contentview } from '../views/contentview';
import { footerview } from '../views/footerview';
import { headerview } from '../views/headerview';
import { pasteboard } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';
import { saveshengci } from '../utils/Dbutils';
import { common } from '@kit.AbilityKit';/*** 翻譯應用主頁面組件*/
@Entry
@Component
struct Index {// 源文本和翻譯結果狀態@State @Watch('clear') sourcetext: string = ''    // 源文本,監聽變化@State targettext: string = ''                    // 翻譯結果private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext  // 應用上下文/*** 源文本清空時的監聽函數* 當源文本為空時,清空翻譯結果*/clear() {if (this.sourcetext === '') {this.targettext = ''}}/*** 翻譯結果回調函數* @param data 翻譯返回的數據* @description 處理翻譯結果并更新到目標文本*/cb(data: string) {getResult(data)?.forEach((item) => {this.targettext += item})}/*** 執行翻譯操作* @description * 1. 檢查源文本是否為空* 2. 清空之前的翻譯結果* 3. 調用翻譯API* 4. 處理可能的錯誤*/to: () => void = () => {if (this.sourcetext) {this.targettext = ''postllm(this.sourcetext, this.cb.bind(this)).catch((e: string) => {console.error('gxxt ', e)})} else {AlertDialog.show({title: '提示', message: '請輸入要翻譯的內容', confirm: {value: '確定', action: () => {}}})}}/*** 復制翻譯結果到剪貼板* @description * 1. 檢查是否有翻譯結果* 2. 創建剪貼板數據* 3. 設置到系統剪貼板* 4. 顯示操作結果提示*/cpck: () => void = () => {if (this.targettext !== '') {let pasttext = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, this.targettext)let jianqieban = pasteboard.getSystemPasteboard()jianqieban.setDataSync(pasttext)promptAction.showToast({ message: '已經復制到剪切板' })} else {promptAction.showToast({ message: '沒有翻譯結果,無法復制到剪切板' })}}/*** 保存到生詞本* @description * 1. 記錄翻譯內容* 2. 記錄原文* 3. 記錄保存時間*/tobeiwanglu: () => void = () => {saveshengci({content: this.targettext,trans: this.sourcetext,time: gettime()}, this.context)}/*** 構建UI界面* @description * 1. 頂部標題欄* 2. 中間內容區域(源文本和翻譯結果)* 3. 底部操作欄(復制和生詞本功能)*/build() {Column() {headerview({ text: '星星翻譯', isleft: false })contentview({ sourcetext: this.sourcetext, targettext: this.targettext, transopt: this.to })footerview({ clipck: this.cpck, tobeiwanglu: this.tobeiwanglu })}.width('100%').height('100%')}
}

子組件contentview核心代碼:

/*** contentview.ets* 翻譯內容視圖組件* 提供文本輸入、翻譯結果顯示、文本選擇、復制、生詞本等功能*/import { promptAction } from "@kit.ArkUI"
import { pasteboard } from "@kit.BasicServicesKit"
import { saveshengci } from "../utils/Dbutils"
import { posttxt } from "../utils/HttpUtils"
import { common } from "@kit.AbilityKit"
import { gettime } from "../utils/StringUtils"/***作者:gxx*時間:2025/5/6 14:51*功能:**/
@Preview
@Component
export struct contentview {// 源文本,用于存儲用戶輸入的待翻譯文本@Link sourcetext: string// 目標文本,用于存儲翻譯結果@Link targettext: string// 獲取UI上下文private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext// 翻譯操作回調函數transopt: () => void = () => {}// 當前選中的文本private selecttext: string = ''// 是否全選狀態@State isquanxuan: boolean = false// 是否顯示菜單@State ismenushow: boolean = truebuild() {Stack() {Column() {// 輸入區域Column() {TextArea({ placeholder: '要翻譯的文本' }).width('100%').height('100%').backgroundColor(Color.Transparent).onChange((value) => {this.sourcetext = value.trim()})}.width('100%').height('45%').padding(10).border({ width: 2, color: '#eee' }).borderRadius({ topLeft: 10, topRight: 10 }).backgroundColor(Color.White)// 翻譯結果區域Column() {Scroll() {Text(this.targettext === '' ? '翻譯結果' : this.targettext).width('100%').copyOption(CopyOptions.InApp).fontWeight(FontWeight.Bolder).backgroundColor(Color.Transparent).fontColor(this.targettext === '' ? Color.Gray : Color.Black)// 綁定長按菜單.bindSelectionMenu(TextSpanType.TEXT, this.genselectmenu(), TextResponseType.LONG_PRESS, {onDisappear: () => {this.ismenushow = truethis.isquanxuan = false}})// 文本選擇變化監聽.onTextSelectionChange((start: number, end: number) => {this.selecttext = this.targettext.substring(start, end)})// 全選狀態控制.selection(this.isquanxuan ? 0 : -1, this.isquanxuan ? this.targettext.length : 0)}.scrollable(ScrollDirection.Vertical)}.width('100%').height('45%').padding(10).backgroundColor('#eee').borderRadius({ bottomLeft: 10, bottomRight: 10 })}.width('100%').height('100%').justifyContent(FlexAlign.SpaceBetween)// 翻譯按鈕SymbolGlyph($r('sys.symbol.reverse_order')).fontSize(35).fontWeight(FontWeight.Bolder).border({ width: 2, radius: 10 }).padding(5).stateStyles({normal: {.backgroundColor(Color.White)},pressed: {.backgroundColor(Color.Gray)}}).onClick(() => {this.transopt()})}.width('100%').height('80%').padding(10)}/*** 生成文本選擇菜單* 包含復制、全選、添加到生詞本等功能*/@Buildergenselectmenu() {Row({ space: 15 }) {// 復制按鈕Text('復制').fontSize(12).onClick(() => {let pasttext = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, this.selecttext)let jianqieban = pasteboard.getSystemPasteboard()jianqieban.setDataSync(pasttext)promptAction.showToast({ message: '已經復制到剪切板' })this.ismenushow = false})// 全選按鈕(僅在非全選狀態顯示)if (!this.isquanxuan) {Text('全選').fontSize(12).onClick(() => {this.isquanxuan = true})}// 生詞本按鈕Text('生詞本').fontSize(12).onClick(() => {this.ismenushow = falseif (this.isquanxuan) {// 全選狀態下保存整個翻譯結果saveshengci({content: this.targettext,trans: this.sourcetext,time: gettime()}, this.context)} else {// 選中狀態下翻譯選中文本并保存posttxt(this.selecttext).then((value) => {let target = value.query// 拼接好的翻譯結果let source = value.translation.join(',')saveshengci({content: target,trans: source,time: gettime()}, this.context)}).catch((e: Error) => {console.error('gxxt 文本翻譯結果: ', e.message)})}})}.backgroundColor(Color.White).padding(10).borderRadius(20).border({ width: 1 }).visibility(this.ismenushow ? Visibility.Visible : Visibility.None)}
}

生詞本頁面代碼

這是一個生詞本界面,采用簡潔現代的設計風格。界面頂部是標題欄,顯示"生詞本"標題,左側配有返回按鈕,方便用戶返回上一頁面。

主體部分是一個可滾動的生詞列表,每個生詞條目以卡片形式展示,包含兩個主要信息:上方顯示生詞內容,采用較大字號和粗體樣式;下方顯示對應的翻譯內容,使用灰色字體。每個條目右側都有一個箭頭圖標,提示用戶可以點擊查看詳情。

用戶可以通過左滑生詞條目來顯示刪除按鈕,點擊刪除按鈕會彈出確認對話框,防止誤操作。點擊生詞條目會彈出一個詳情對話框,以更大的字體展示完整的生詞內容和翻譯,并顯示保存時間。如果內容較長,對話框支持滾動查看。

/*** shengciben.ets* 生詞本頁面組件* 提供生詞列表展示、詳情查看、刪除等功能*/import { shengci } from '../model/shengci';
import { delbyid, querylimit } from '../utils/Dbutils';
import { common } from '@kit.AbilityKit';
import { headerview } from '../views/headerview';
import { ComponentContent, router } from '@kit.ArkUI';/*** 生成生詞詳情對話框* @param p 對話框參數,包含生詞信息、刪除回調、滾動高度等*/
@Builder
function gendialog(p: param) {Stack() {// 關閉按鈕SymbolGlyph($r('sys.symbol.xmark')).fontSize(20).onClick(() => {p.delck()}).zIndex(2)Column({ space: 10 }) {// 標題Text('生詞詳情').fontSize(25).fontWeight(FontWeight.Bolder)Divider().color(Color.Grey).margin({ top: 10, bottom: 10 })// 內容區域Scroll() {Column({ space: 10 }) {// 生詞內容Text(p.item.content).fontSize(18).fontWeight(FontWeight.Bold)// 翻譯內容Text(p.item.trans).fontSize(14).fontColor(Color.Gray)}.alignItems(HorizontalAlign.Start)}.height(p.scrollheight)Divider().color(Color.Grey).margin({ top: 10, bottom: 10 })// 時間信息Text('時間:').fontSize(18).fontWeight(FontWeight.Bold)Text(p.item.time).fontSize(14).fontColor(Color.Gray)}.width('100%').alignItems(HorizontalAlign.Start)}.width('80%').borderRadius(10).alignContent(Alignment.TopEnd).backgroundColor(Color.White).border({ width: 1 }).padding(10)
}/*** 對話框參數接口*/
interface param {item: shengci,        // 生詞信息delck: () => void,    // 刪除回調函數scrollheight: Length, // 滾動區域高度
}/*** 生詞本頁面組件*/
@Entry
@Component
struct Shengciben {@State message: string = 'Hello World';@State datas: shengci[] = []  // 生詞列表數據private builder: ComponentContent<param> | null = nullprivate context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext/*** 組件即將出現時加載數據*/aboutToAppear(): void {querylimit(this.context, 1).then((value) => {this.datas = value}).catch((e: Error) => {console.error('gxxt 查詢生詞本錯誤: ', e.message)})}build() {Column() {// 頂部標題欄headerview({text: '生詞本', isright: false, leftck: () => {router.back()}})// 生詞列表List({ space: 5 }) {ForEach(this.datas, (item: shengci, index: number) => {ListItem() {this.genlistitem(item)}.swipeAction({ end: this.genitemend(item.id, index) })  // 左滑顯示刪除按鈕.onClick(() => {// 點擊顯示詳情彈窗let p: param = {item: item,delck: () => {this.getUIContext().getPromptAction().closeCustomDialog(this.builder)},scrollheight: item.content.length + item.trans.length > 150 ? 300 : 'auto'}this.builder = new ComponentContent(this.getUIContext(), wrapBuilder<[param]>(gendialog), p)this.getUIContext().getPromptAction().openCustomDialog(this.builder, {alignment: DialogAlignment.Center})})})}.margin({ top: 5 })}.width('100%').height('100%')}/*** 生成列表項右滑刪除按鈕* @param id 生詞ID* @param index 列表索引*/@Buildergenitemend(id: number, index: number) {Row() {SymbolGlyph($r('sys.symbol.trash_fill')).fontSize(30).fontColor([Color.Red])}.padding({left: 10,top: 5,bottom: 5,right: 10}).border({ width: 1, radius: 10 }).margin(5).onClick(() => {// 刪除確認對話框AlertDialog.show({title: '提示',message: '確定要刪除嗎?',primaryButton: {value: '確定', action: () => {delbyid(id, this.context).then(() => {this.datas.splice(index, 1)})}},secondaryButton: {value: '取消', action: () => {}}})})}/*** 生成列表項內容* @param item 生詞信息*/@Buildergenlistitem(item: shengci) {Row() {Column({ space: 5 }) {// 生詞內容Text(item.content).fontSize(20).fontWeight(FontWeight.Bolder).width('60%').textOverflow({ overflow: TextOverflow.Ellipsis }).maxLines(1)// 翻譯內容Text(item.trans).fontSize(14).fontColor(Color.Gray).width('60%').textOverflow({ overflow: TextOverflow.Ellipsis }).maxLines(1)}Blank()// 右箭頭圖標SymbolGlyph($r('sys.symbol.chevron_right')).fontSize(20)}.width('100%').padding({left: 5,top: 10,bottom: 10,right: 5}).border({ width: 1, radius: 5 })}
}

完整項目代碼:

https://download.csdn.net/download/gao_xin_xing/90892395

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/907308.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907308.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907308.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vim 中設置插入模式下輸入中文

在 Vim 中設置插入模式下輸入中文需要配置輸入法切換和 Vim 的相關設置。以下是詳細步驟&#xff1a; 1. 確保系統已安裝中文輸入法 在 Linux 系統中&#xff0c;常用的中文輸入法有&#xff1a; IBus&#xff08;推薦&#xff09;&#xff1a;支持拼音、五筆等Fcitx&#xf…

湖北理元理律師事務所:債務優化中的“生活錨點”設計

在債務重組領域&#xff0c;一個常被忽視的核心矛盾是&#xff1a;還款能力與生存需求的沖突。過度壓縮生活支出還債&#xff0c;可能導致收入中斷&#xff1b;放任債務膨脹&#xff0c;又加劇精神壓力。湖北理元理律師事務所通過“三步平衡法”&#xff0c;嘗試在法理框架內破…

Prometheus + Grafana 監控常用服務

一、引言 Prometheus監控常見服務的原理主要包括服務暴露指標和Prometheus抓取指標。一方面&#xff0c;被監控服務通過自身提供的監控接口或借助Exporter將服務的性能指標等數據以HTTP協議的方式暴露出來&#xff1b;另一方面&#xff0c;Prometheus根據配置好的采集任務&…

基于YOLOv8 的分類道路目標系統-PyTorch實現

本文源碼: https://download.csdn.net/download/shangjg03/90873939 1. 引言 在智能交通和自動駕駛領域,道路目標分類是一項關鍵技術。通過對攝像頭捕獲的圖像或視頻中的目標進行分類識別,可以幫助車輛或系統理解周圍環境,做出更安全的決策。本教程將介紹如何使用 PyTorch …

知識圖譜:AI時代語義認知的底層重構邏輯

在生成式人工智能&#xff08;GEO&#xff09;的技術架構中&#xff0c;知識圖譜已從輔助性工具演變為驅動機器認知的核心神經中樞。它通過結構化語義網絡的重構&#xff0c;正在突破傳統數據處理的線性邏輯&#xff0c;建立機器對復雜業務場景的深度理解能力。 一、語義解構&a…

如何使用 Python 的膠水語言特性

Python 作為“膠水語言”最核心的特性在于&#xff1a;跨語言集成能力強、支持豐富的 C/C 擴展模塊、嵌入式調用簡便、適配多種數據交換格式、擁有強大的封裝能力。其中&#xff0c;Python 對 C/C 模塊的快速封裝能力&#xff0c;使其能夠將底層高性能庫暴露為易用接口&#xf…

[網頁五子棋][匹配模塊]服務器開發、用戶管理器(創建匹配請求/響應對象、處理連接成功、處理下線)

文章目錄 MatchAPI 類用戶管理器創建匹配請求/響應對象處理連接成功—afterConnectionEstablished處理下線——handleTransportError/afterConnectionClosed MatchAPI 類 創建 api.MatchAPI&#xff0c;繼承自 TextWebSocketHandler 作為處理 WebSocket 請求的入口類 準備好一…

軟件測試的潛力與挑戰:從“質量守門員”到“工程效能催化劑”的進化

1. 潛力&#xff1a;為什么軟件測試的未來比想象中更廣闊&#xff1f; ? 行業趨勢驅動需求爆發 DevOps/持續交付&#xff1a;測試成為流水線的核心環節&#xff0c;自動化能力直接影響發布頻率&#xff08;案例&#xff1a;某頭部互聯網企業日均發布100次&#xff0c;依賴自動…

indel_snp_ssr_primer

好的&#xff0c;我們可以逐步分析這個 Perl 腳本的每個部分。腳本的主要功能是基于給定的 VCF 文件和參考基因組文件&#xff0c;設計引物并進行電子 PCR&#xff08;e-PCR&#xff09;分析。我們將從腳本的頭部和初始化部分開始講解。 第一部分&#xff1a;腳本頭部和初始化…

2.4GHz 射頻前端芯片AT2401C

射頻前端芯片作為無線通信系統的核心組件&#xff0c;涵蓋功率放大器&#xff08;PA&#xff09;、濾波器、開關、低噪聲放大器&#xff08;LNA&#xff09;等關鍵器件&#xff0c;其性能直接影響通信質量、功耗及信號穩定性。 AT2401C是一款面向 Zigbee&#xff0c;無線傳感網…

Batch Normalization[[

error surface如果很崎嶇,那么就代表比較難train,我們有沒有辦法去改變這個landscape呢 可以用batch normalization. 如果 ( x_1 ) 的取值范圍很小&#xff08;如 1, 2&#xff09;&#xff0c;而 ( x_2 ) 的取值范圍很大&#xff08;如 100, 200&#xff09;&#xff0c;那么…

c++結構化綁定

author: hjjdebug date: 2025年 05月 28日 星期三 15:57:58 CST descrip: c結構化綁定: 結構化綁定: 名稱辨析: 名稱叫綁定好還是叫解綁好&#xff1f; 解綁意思是原來是一個整體,現在被分成了若干個部分,所以叫解. 綁定強調的意思是. 被分解的某個變量,綁定到了整體的某個變量…

大數據治理:理論、實踐與未來展望(一)

文章目錄 一、大數據治理的定義與重要性&#xff08;一&#xff09;定義&#xff08;二&#xff09;重要性 二、大數據治理的應用場景&#xff08;一&#xff09;金融行業&#xff08;二&#xff09;醫療行業&#xff08;三&#xff09;制造業&#xff08;四&#xff09;零售行…

AI系統化學習月計劃6月計劃

以下是為技術總監設計的 AI系統化學習月計劃&#xff08;每天投入2小時&#xff0c;共30天&#xff09;&#xff0c;結合戰略思維、技術基礎、實戰應用和行業趨勢&#xff0c;幫助您快速掌握AI的核心知識&#xff0c;并轉化為業務決策能力。 第一周&#xff1a;AI基礎與戰略思維…

詳解MySQL調優

目錄 1. SQL 語句優 1.1 避免低效查詢 1.2 索引優化 1.3 分析執行計劃 2. 數據庫配置優化 2.1 核心參數調整 2.2 表結構與存儲引擎 2.3 存儲引擎選擇 3. 事務與鎖優化 3.1 事務控制 3.2 鎖機制優化 3.3 批量操作優化 4. 其他優化手段 4.1 監控與分析工具 4.2 讀寫…

VScode單雙引號、分號格式

1、settings.json中添加&#xff1a; 1 2 3 "prettier.semi": false, // 取消自動加分號 "prettier.singleQuote": true, // 保持單引號&#xff0c;不自動變雙引號 "prettier.trailingComma": "none" // 去掉結尾的逗號 2、如上一步…

自動駕駛規劃控制教程——不確定環境下的決策規劃

引言:駕馭未知——不確定性下的自動駕駛決策挑戰 自動駕駛汽車 (Autonomous Vehicles, AVs) 的愿景是徹底改變交通運輸的面貌,提高道路安全、提升交通效率、改善駕乘體驗。然而,要將這一愿景安全可靠地付諸實踐,自動駕駛系統必須能夠在復雜、動態且充滿不確定性的真實世界…

電纜中性點概念

電纜中性點概念 電纜中性點(也稱“中性點”或“中性線”)是電力系統和電氣設備中一個非常重要的概念,尤其在三相電系統中。下面是對中性點概念的系統性解釋。 1. 基本定義 中性點:三相電纜(A/B/C相)的電壓矢量交匯點,理想情況下三相平衡時該點電壓為零。對于星形(Y形…

MyBatis 動態 SQL 詳解:靈活構建強大查詢

MyBatis 的動態 SQL 功能是其最強大的特性之一&#xff0c;它允許開發者根據不同條件動態生成 SQL 語句&#xff0c;極大地提高了 SQL 的靈活性和復用性。本文將深入探討 MyBatis 的動態 SQL 功能&#xff0c;包括 OGNL 表達式的使用以及各種動態 SQL 元素&#xff08;如 if、c…

嵌入式自學第三十天(5.28)

&#xff08;1&#xff09;多線程資源競爭問題&#xff1a; 互斥&#xff1a;在多線程中對臨界資源的排他性訪問。 解決方案&#xff1a;互斥鎖 mutex互斥鎖在進程pcb塊&#xff0c;ret 為0說明別人在用&#xff0c;1說明空閑。 阻塞鎖 man pthread_mutex_init man pthread_…