最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Spring AI+MySQL實(shí)現(xiàn)文件內(nèi)容相似度的簡單檢測

 更新時間:2025年11月12日 09:56:51   作者:南清在coding  
在做一個 AI 求職的比賽項(xiàng)目中,遇到了一個有趣的需求:用戶上傳自己的簡歷文件后,系統(tǒng)需要計(jì)算并返回該簡歷與其他用戶簡歷之間的相似度,想要實(shí)現(xiàn)這樣的功能,所以本文給大家分享了如何基于Spring AI+MySQL實(shí)現(xiàn)文件內(nèi)容相似度的簡單檢測,需要的朋友可以參考下

前言

在做一個 AI 求職的比賽項(xiàng)目中,遇到了一個有趣的需求:用戶上傳自己的簡歷文件后,系統(tǒng)需要計(jì)算并返回該簡歷與其他用戶簡歷之間的相似度。想要實(shí)現(xiàn)這樣的功能,這就意味著我們經(jīng)過如下的步驟:

熟悉向量檢索的話可能知道,借助 Redisearch 可以將 Redis 用作向量數(shù)據(jù)庫;然而,考慮到這只是一個學(xué)生比賽項(xiàng)目,初期并未引入 Redis 。因此,我們最終選擇了 Spring AI + MySQL 的方案,而且在實(shí)踐過程中也可以簡要學(xué)習(xí)到很多大模型的知識。為了便于講解和演示,我將這部分功能單獨(dú)抽離出來。在這篇博客中,你可以了解到:

  • SpringAI 使用向量模型的前置工作
  • 在 SpringAI 中如何使用向量模型
  • 如何編碼實(shí)現(xiàn)余弦相似度檢測
  • 如何編碼實(shí)現(xiàn)小頂堆 TopK 檢索

由于篇幅限制,本文僅展示部分核心代碼。如果你對完整實(shí)現(xiàn)感興趣,歡迎訪問我的 Gitee 倉庫(gitee.com/nanqq/nanq-coding)獲取全部示例代碼,運(yùn)行效果如下:

接下來就依次拆解搭建步驟。

前置工作01:使用 Apache Tika 提取文件文本

Apache Tika 是用于自動識別文件類型并提取文本與元數(shù)據(jù)的開源工具包,通過 Tika ,我們可以將 非結(jié)構(gòu)化文檔轉(zhuǎn)為可處理的文本 ,為后續(xù)的向量化和相似度檢索提供輸入。首先需要引入依賴:

<!-- Apache Tika 核心功能 -->
<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-core</artifactId>
    <version>2.9.2</version>
</dependency>

<!-- Apache Tika 標(biāo)準(zhǔn)解析器包,支持多種文件格式(PDF、Word、Excel、PPT 等) -->
<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-parsers-standard-package</artifactId>
    <version>2.9.2</version>
</dependency>

想要上傳文件給 TiKa 處理,就需要文件上傳的接口,接收上傳文件并從文件輸入流提取文本。

/**
* 上傳文件,抽取可讀文本內(nèi)容
*/
@PostMapping(value = "/{textId}/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public UploadResp uploadAndVectorize(@PathVariable Long textId, @RequestPart("file") MultipartFile file) throws Exception {
        String mime = file.getContentType();
        String name = file.getOriginalFilename();
        // 通過 Tika 抽取文本
        String content = tika.parseToString(file.getInputStream());
        // ...
}

通過這里的代碼就可以發(fā)現(xiàn),Tika 是很簡單易用的,僅需一行代碼 就可以完成文本提取。而且還 支持多種格式 ,比如PDF、Word、Excel、PPT、TXT 等。

前置工作02:自定義文本分段器進(jìn)行文本分段

因?yàn)?Tika 只負(fù)責(zé)文本提取,并不負(fù)責(zé)分段,所以我們就需要自定義分段的邏輯。那么為什么 Tika 做了文本解析的工作,還需要文本分段呢?主要有以下幾點(diǎn)原因:

  • 向量化需要合適長度的文本,將整個文檔作為單個向量會丟失很多細(xì)節(jié)
  • 模型對文本長度有限制,過長文本可能被截斷
  • 計(jì)算相似度是按片段以定位具體相似部分,文檔粒度太大,就無法定位到具體相似段落

接下來我們就繼續(xù)實(shí)現(xiàn) 自定義文本分段器 。

編碼實(shí)現(xiàn)文本分段器

首先,我們將  Tika 提取出的文本與句子按照一定的規(guī)則進(jìn)行 規(guī)范化 :

// 規(guī)范化并按句末標(biāo)點(diǎn)分句:將句末標(biāo)點(diǎn)后插入換行,再按空行切分
String[] raw = text.replace('\r', '\n') // 換行符
    .replaceAll("[。???!?]", "$0\n") // 在句末標(biāo)點(diǎn)后插入換行,保留原標(biāo)點(diǎn)
    .split("\n+"); // 按連續(xù)換行分割

這段代碼比較生硬,在這里舉一個被這段代碼處理后的例子:

輸入: "這是第一句。這是第二句!這是第三句?"
代碼處理后: ["這是第一句。", "這是第二句!", "這是第三句?"]

然后 清洗文本 ,以得到可用的句子列表:

// 清洗:去空白、移除空串
List<String> cleaned = Arrays.stream(raw)
    .map(String::trim)
    .filter(s -> !s.isEmpty())
    .collect(Collectors.toList());

最后 控制片段的長度 ,分段規(guī)則與代碼實(shí)現(xiàn)如下:

場景句子長度處理方式原因
正常句子< 500字聚合段(緩沖區(qū)累積)可以累積多個短句,達(dá)到300字目標(biāo)。沒有緩沖區(qū),有的向量片段過短,導(dǎo)致向量效果差
超長句子≥ 500字硬切(直接切分)單個句子就超過限制,必須硬切,不能累積
List<String> result = new ArrayList<>();
        StringBuilder buf = new StringBuilder();
        for (String s : cleaned) {
            // 聚合段:控制單段最大到 300 字,超過則先輸出緩沖區(qū)
            if (buf.length() + s.length() > 300) {
                if (buf.length() > 0) {
                    result.add(buf.toString());
                    buf.setLength(0);
                }
            }
            // 超長句子:按 500 字硬切,保證不會出現(xiàn)過長片段
            if (s.length() > 500) {
                for (int i = 0; i < s.length(); i += 500) {
                    result.add(s.substring(i, Math.min(s.length(), i + 500)));
                }
            } else {
                if (buf.length() > 0) buf.append('\n');
                buf.append(s);
            }
        }

在 SpringAI 中如何使用向量模型

向量模型是什么

向量模型(Embedding Model)將文本轉(zhuǎn)換為 數(shù)值向量(數(shù)值向量就是浮點(diǎn)數(shù)數(shù)組),將語義信息編碼為可計(jì)算的數(shù)值。語義相近的文本,其向量在空間中更接近 。 例如:

  • 文本:"我喜歡編程" → 向量:[0.23, -0.45, 0.67, ..., 0.12]
  • 文本:"我愛寫代碼" → 向量:[0.25, -0.43, 0.65, ..., 0.11]

那為什么需要向量模型呢?傳統(tǒng)文本只能做字面匹配,無法理解語義。例如:"汽車" 和 "車輛" 在傳統(tǒng)方法中不匹配,但語義相近。向量模型能捕捉 語義相似性 ,以及進(jìn)行向量相似度的 快速計(jì)算 ,適合在海量文檔中查找相似內(nèi)容。

SpringAI 配置向量模型

完成了對于文件處理的前置工作,以及了解簡單的概念后,就可以使用向量模型了。想要在 SpringAI 中使用向量模型,首先需要 引入 SpringAI 依賴 :

<!-- SpringAI DashScope -->
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    <version>1.0.0.4</version>
</dependency>

在配置文件里,也需要配置我們想要使用的 向量模型 :

  ai:
    dashscope:
      api-key: your-api-key
      embedding:
        options:
          model: text-embedding-v2

與普通的對話大模型不同,text-embedding-v2 是專門用于文本向量化的模型。Spring AI 提供了一個 EmbeddingModel 接口,用于將 文本或文檔轉(zhuǎn)換為向量 。SpringAI 可以根據(jù)配置自動創(chuàng)建 Bean,在這里,我們通過構(gòu)造函數(shù)注入使用:

private final EmbeddingModel embeddingModel;

向量入庫與出庫

首先需要對文件進(jìn)行 文本分段處理 。使用我們之前自定義的自定義文本分段器即可:

private final TextSegmenter textSegmenter;

// ...

List<String> segments = textSegmenter.segment(fullText);
if (segments.isEmpty()) return 0;

文本分段完成后,就需要調(diào)用向量模型 計(jì)算向量 :

// 計(jì)算嵌入向量
float[] vectorArray = embeddingModel.embed(seg); 

在控制臺的輸出中,我們可以發(fā)現(xiàn) 文本片段被轉(zhuǎn)換為浮點(diǎn)數(shù)數(shù)組 :

隨后將 向量序列化 以方便入庫:

// 向量序列化與存儲
String segmentId = segmentIdGenerator.idFor(seg);
String content = seg;
if (content != null && content.length() > 500) content = content.substring(0, 500);
DocumentVector dv = new DocumentVector();
dv.setTextId(textId);
dv.setSegmentId(segmentId);
dv.setContent(content);
dv.setEmbeddingVector(vectorCodec.serialize(vectorArray));

序列化的具體實(shí)現(xiàn)使用 JSON 格式 ,便于存儲與讀?。?/p>

private final ObjectMapper objectMapper;

// ...

@Override
public String serialize(float[] vector) {
    try {
        // 以 JSON 數(shù)組形式持久化
        return objectMapper.writeValueAsString(vector);
    } catch (Exception e) {
        throw new IllegalStateException("序列化嵌入向量失敗", e);
    }
}

相反地,在從數(shù)據(jù)庫讀取時也需要 反序列化 ,便于進(jìn)行后續(xù)的相似度計(jì)算:

// 反序列化向量,構(gòu)建便于計(jì)算的數(shù)據(jù)結(jié)構(gòu)
Map<String, double[]> segVec = new HashMap<>();
for (var s : segments) {
    segVec.put(s.getSegmentId(), vectorCodec.deserialize(s.getEmbeddingVector()));
}
Map<DocumentVector, double[]> corpusMap = new HashMap<>();
for (var c : corpus) {
    corpusMap.put(c, vectorCodec.deserialize(c.getEmbeddingVector()));
}

反序列化的具體實(shí)現(xiàn)也是將 JSON 字符串還原為數(shù)組 :

public double[] deserialize(String json) {
    //...
    try {
         // 直接反序列化為 double[],配合后續(xù)相似度計(jì)算的雙精度實(shí)現(xiàn)
        double[] arr = objectMapper.readValue(json, double[].class);
        return arr == null ? new double[0] : arr;
            } catch (Exception e) {
                throw new IllegalArgumentException("反序列化嵌入向量失敗", e);
        }
}

相似度計(jì)算

在相似度計(jì)算中,我們采用 小頂堆檢索與余弦相似度相結(jié)合 的方案。

大致而言,小頂堆作為一種高效的 TopK 檢索算法,專注于從大量候選中快速找出 最相似的 K 個結(jié)果 ;而余弦相似度則作為衡量向量間相似程度的度量標(biāo)準(zhǔn),負(fù)責(zé)計(jì)算 樣本之間的相似性 。

在該方案中,小頂堆以余弦相似度作為比較依據(jù),動態(tài)維護(hù)當(dāng)前最優(yōu)的 TopK 結(jié)果集 ,從而高效完成相似度檢索任務(wù)。

編碼實(shí)現(xiàn)余弦相似度算法

/**
 * 余弦相似度計(jì)算工具
 */
public class CosineSimilarityUtils {

    /**
     * 計(jì)算兩個向量的余弦相似度
     *
     * @param a 向量A
     * @param b 向量B
     * @return 余弦相似度 [-1, 1]
     */
    public static double cosine(double[] a, double[] b) {
        // 參數(shù)為空/維度不一致直接返回0
        if (a == null || b == null || a.length == 0 || b.length == 0 || a.length != b.length) return 0.0;
        double dot = 0.0;
        double na = 0.0;
        double nb = 0.0;
        // 累計(jì)點(diǎn)積與各自范數(shù)平方
        for (int i = 0; i < a.length; i++) {
            dot += a[i] * b[i];
            na += a[i] * a[i];
            nb += b[i] * b[i];
        }
        // 任一向量為零向量:相似度定義為0,避免除零
        if (na == 0.0 || nb == 0.0) return 0.0;
        return dot / (Math.sqrt(na) * Math.sqrt(nb));
    }
}

然后我們需要進(jìn)行進(jìn)一步的 封裝 ,以便在 TopK 檢索中使用:

/**
 * 相似度度量接口
 * 定義兩向量之間的相似度計(jì)算方式
 */
public interface SimilarityMetric {

    /**
     * 計(jì)算兩個同維度向量的相似度值。
     * @param a 向量A
     * @param b 向量B
     * @return 相似度(數(shù)值越大越相似)
     */
    double similarity(double[] a, double[] b);
}

編碼實(shí)現(xiàn)小頂堆 TopK 檢索算法

小頂堆是一種滿足“父節(jié)點(diǎn)值 ≤ 子節(jié)點(diǎn)值”的完全二叉樹結(jié)構(gòu),其堆頂元素即為當(dāng)前堆中的最小值。

那么,為何在 TopK 檢索中選用小頂堆呢?原因在于:當(dāng)我們維護(hù)一個大小固定為 K 的小頂堆時,堆頂始終代表當(dāng)前選中的 K 個元素中的最小值 。對于新到來的元素,只需將其與堆頂比較——若其值大于堆頂,則說明它有資格進(jìn)入當(dāng)前 TopK,此時可將堆頂替換并重新調(diào)整堆結(jié)構(gòu);反之,若小于或等于堆頂,則可直接忽略。這種機(jī)制既能高效維護(hù) TopK 結(jié)果,又避免了對全部數(shù)據(jù)進(jìn)行排序的高開銷。

那么接下來就嘗試逐步實(shí)現(xiàn)。首先,使用優(yōu)先隊(duì)列 初始化小頂堆 :

PriorityQueue<Map.Entry<T, Double>> heap = new PriorityQueue<>(Map.Entry.comparingByValue());

而后,遍歷語料以 計(jì)算相似度 :

for (Map.Entry<T, double[]> e : corpus.entrySet()) {
    double[] v = e.getValue();
    // 維度不一致直接跳過
    if (v == null || v.length != query.length) continue;
    double sim = metric.similarity(query, v); // 使用余弦相似度
    // ...
 }

以及實(shí)現(xiàn) 維護(hù)小頂堆 的編碼邏輯:

if (heap.size() < k) {
        // 未滿K,直接入堆
        heap.offer(Map.entry(e.getKey(), sim));
    } else if (heap.peek().getValue() < sim) {
        // 比堆頂大:彈出最小,再加入
        heap.poll();
        heap.offer(Map.entry(e.getKey(), sim));
}

最后 排序輸出 。將堆轉(zhuǎn)為列表,并按相似度降序排序,最后返回 TopK 結(jié)果:

// 結(jié)果按相似度降序輸出
List<Map.Entry<T, Double>> top = new ArrayList<>(heap);
top.sort((a, b) -> Double.compare(b.getValue(), a.getValue()));
return top;

在項(xiàng)目中,兩者相互配合,找出 最相近的候選片段 :

for (var s : segments) {
    double[] v = segVec.get(s.getSegmentId());
    if (v == null || v.length == 0) continue;
    // 使用 TopK 檢索策略 + 相似度度量,獲取最相近候選
    List<Map.Entry<DocumentVector, Double>> top = topKSearcher.topK(v, corpusMap, k, similarityMetric);
}

相似度報告生成實(shí)現(xiàn)

至此,最核心的處理流程實(shí)際上已經(jīng)完成。然而,直接向客戶展示一堆原始數(shù)據(jù)或數(shù)值顯然不夠友好,因此還需對結(jié)果進(jìn)行進(jìn)一步加工與組織,最終生成清晰、易讀的報告,以便用戶直觀理解。

在調(diào)用相似度計(jì)算接口時,首先對用戶輸入的參數(shù)進(jìn)行合法性校驗(yàn):

public SimilarityReportDTO computeSimilarityReport(Long textId, Integer topK, Double threshold) {
    // TopK 合法化:限制在 [1, 20],默認(rèn)為 5
    int k = topK == null ? 5 : Math.max(1, Math.min(20, topK));
    // 閾值夾取:限制在 [0.5, 0.99],默認(rèn)為 0.90
    double tau = threshold == null ? 0.90 : Math.max(0.5, Math.min(0.99, threshold));
    // ...
}    

接下來,分別加載待檢測文本的片段向量和用于比對的語料庫:

// segments:當(dāng)前文本(textId)的所有片段向量
List<DocumentVector> segments = documentVectorMapper.selectByTextId(textId);
if (segments == null || segments.isEmpty()) {
    throw new RuntimeException("該文本尚未向量化");
}
// corpus:排除當(dāng)前文本后的其他文檔片段
List<DocumentVector> corpus = documentVectorMapper.selectCorpusForSimilarity(textId);
if (corpus == null || corpus.isEmpty()) {
    throw new RuntimeException("對比語料為空");
}

對應(yīng)的 SQL 查詢?nèi)缦?,最多?2000 條作為比對語料:

<select id="selectCorpusForSimilarity" parameterType="long" resultMap="DocumentVectorMap">
    SELECT * FROM document_vector
    WHERE text_id != #{excludeTextId}
    LIMIT 2000
</select>

對每個待檢片段,在語料庫中執(zhí)行 TopK 相似片段檢索,并記錄關(guān)鍵指標(biāo):

int highSimCount = 0;
double sumTopSim = 0.0;

for (var s : segments) {
    double[] v = segVec.get(s.getSegmentId());
    if (v == null || v.length == 0) continue;

    List<Map.Entry<DocumentVector, Double>> top = topKSearcher.topK(v, corpusMap, k, similarityMetric);
    if (top.isEmpty()) continue;

    double bestSim = top.get(0).getValue(); // 取 Top1 相似度
    sumTopSim += bestSim;
    if (bestSim >= tau) highSimCount++;
}

基于結(jié)果,聚合生成全局的評估指標(biāo)。具體規(guī)則與代碼實(shí)現(xiàn)如下:

指標(biāo)計(jì)算方式
覆蓋率(Coverage)達(dá)到閾值(≥τ)的片段數(shù) / 總片段數(shù)
平均 Top1 相似度(AvgTopSim)所有片段最高相似度的算術(shù)平均值
綜合評分(Overall Score)100 × (0.6 × Coverage + 0.4 × AvgTopSim)
風(fēng)險等級(Risk Level)HIGH(≥70)、MEDIUM(40–69)、LOW(<40)
double coverage = segments.isEmpty() ? 0 : (double) highSimCount / segments.size(); // 達(dá)閾值片段占比
double avgTopSim = segments.isEmpty() ? 0 : (sumTopSim / segments.size());          // 平均最高相似度
double overall = 100.0 * (0.6 * coverage + 0.4 * avgTopSim);                       // 加權(quán)綜合評分
String risk = overall >= 70 ? "HIGH" : (overall >= 40 ? "MEDIUM" : "LOW");         // 風(fēng)險等級判定

最后生成報告 DTO ,將計(jì)算結(jié)果封裝為標(biāo)準(zhǔn)化的報告對象,便于前端展示:

SimilarityReportDTO report = new SimilarityReportDTO();
report.setTextId(textId);
report.setCoverage(coverage);
report.setAvgTopSim(avgTopSim);
report.setOverallScore(Math.round(overall * 10.0) / 10.0); // 保留一位小數(shù)
report.setRiskLevel(risk);
report.setGeneratedAt(LocalDateTime.now());
return report;

以上就是基于Spring AI+MySQL實(shí)現(xiàn)文件內(nèi)容相似度的簡單檢測的詳細(xì)內(nèi)容,更多關(guān)于Spring AI MySQL文件內(nèi)容相似度檢測的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Boot XSS 攻擊過濾插件使用

    Spring Boot XSS 攻擊過濾插件使用

    這篇文章主要介紹了Spring Boot XSS 攻擊過濾插件使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • 通過IEAD+Maven快速搭建SSM項(xiàng)目的過程(Spring + Spring MVC + Mybatis)

    通過IEAD+Maven快速搭建SSM項(xiàng)目的過程(Spring + Spring MVC + Mybatis)

    這篇文章主要介紹了通過IEAD+Maven快速搭建SSM項(xiàng)目的過程(Spring + Spring MVC + Mybatis),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Springboot使用@Aspect、自定義注解記錄日志方式

    Springboot使用@Aspect、自定義注解記錄日志方式

    本文介紹了如何使用AOP技術(shù)進(jìn)行日志記錄,包括掃描包和自定義注解兩種方式,掃描包方式通過添加依賴和配置切入點(diǎn)表達(dá)式實(shí)現(xiàn),自定義注解方式則通過創(chuàng)建自定義注解和AOP切面類來實(shí)現(xiàn)方法執(zhí)行時間的統(tǒng)計(jì)和記錄
    2024-11-11
  • Spring中AOP概念與兩種動態(tài)代理模式原理詳解

    Spring中AOP概念與兩種動態(tài)代理模式原理詳解

    AOP是面向切面編程的技術(shù),AOP基于IoC基礎(chǔ),是對OOP的有益補(bǔ)充,流行的AOP框架有Sping AOP、AspectJ,這篇文章主要給大家介紹了關(guān)于Spring中AOP概念與兩種動態(tài)代理模式原理的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • 全面解析@InsertProvider執(zhí)行原理

    全面解析@InsertProvider執(zhí)行原理

    這篇文章主要介紹了全面解析@InsertProvider執(zhí)行原理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Windows10系統(tǒng)下JDK1.8環(huán)境變量的配置

    Windows10系統(tǒng)下JDK1.8環(huán)境變量的配置

    今天帶大家學(xué)習(xí)在Windows10系統(tǒng)下怎么配置JDK1.8環(huán)境變量,文中有非常詳細(xì)的安裝及配置教程,對正在學(xué)習(xí)的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • Java中HashMap的初始容量設(shè)置方式

    Java中HashMap的初始容量設(shè)置方式

    這篇文章主要介紹了Java中HashMap的初始容量設(shè)置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java?Bluetooth?藍(lán)牙通訊?BlueCove?掃描附近的藍(lán)牙設(shè)備(測試代碼)

    Java?Bluetooth?藍(lán)牙通訊?BlueCove?掃描附近的藍(lán)牙設(shè)備(測試代碼)

    BlueCove是一個開源的藍(lán)牙協(xié)議棧實(shí)現(xiàn),旨在為Java開發(fā)者提供一個全面的、易于使用的API,從而在應(yīng)用程序中實(shí)現(xiàn)藍(lán)牙功能,該項(xiàng)目支持多種操作系統(tǒng),這篇文章主要介紹了Java?Bluetooth?藍(lán)牙通訊?BlueCove?掃描附近的藍(lán)牙設(shè)備,需要的朋友可以參考下
    2025-01-01
  • Spring Boot緩存問題分析及解決方案

    Spring Boot緩存問題分析及解決方案

    SpringBoot提供緩存支持,提升應(yīng)用性能,但可能出現(xiàn)緩存不一致、緩存穿透、緩存擊穿等問題,分析了緩存基本概念、SpringBoot緩存支持、常見緩存問題及解決方案,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • 詳解Java的位運(yùn)算

    詳解Java的位運(yùn)算

    這篇文章主要介紹了詳解Java的位運(yùn)算,程序中的所有數(shù)在計(jì)算機(jī)內(nèi)存中都是以二進(jìn)制的形式儲存的。位運(yùn)算就是直接對整數(shù)在內(nèi)存中的二進(jìn)制位進(jìn)行操作,需要的朋友可以參考下
    2023-04-04

最新評論

尼勒克县| 台南市| 辉南县| 会东县| 广灵县| 阜新市| 罗平县| 濉溪县| 荔波县| 惠安县| 会宁县| 淳安县| 吉首市| 南昌市| 遂宁市| 湖北省| 左云县| 海丰县| 铁力市| 民勤县| 蕉岭县| 凌云县| 井研县| 奉新县| 南开区| 波密县| 德阳市| 化州市| 舞阳县| 诸城市| 威信县| 八宿县| 江永县| 文登市| 青冈县| 桃江县| 博兴县| 兰西县| 巨野县| 赤壁市| 建昌县|