主頁 > 後端開發 > Java--??面試官:講一下String、StringBuilder及StringBuffer區別???‍【?初學者面試必備?】

Java--??面試官:講一下String、StringBuilder及StringBuffer區別???‍【?初學者面試必備?】

2021-09-04 07:10:37 後端開發

哈嘍,歡迎進來學習的小伙伴~

【學習背景】

本文會通過OpenJDK提供的Java性能測驗工具JMH來測驗下StringStringBuilderStringBuffer拼接字串的效率如何~
關于JMH的介紹及具體使用,我的這篇博文中有介紹:

Java–??面試官:LinkedList真的比ArrayList添加元素快????本文通過Open JDK JMH帶你揭開真相《?建議收藏?》

當然,除了驗證三者的字串拼接效率之外,還會對這三者的特性及常見面試問題進行分析和總結,希望加深自己對這三者的認知,分享出來,也希望能幫助到有需要的小伙伴~

進入正文~~


學習目錄

  • 一、性能測驗
  • 1.1 代碼實作
  • 1.2 測驗結果
    • 1.2.1 普通展示
    • 1.2.2 圖形展示
  • 1.3 結果分析
  • 二、區別說明
    • 2.1 String
      • 2.1.1 String特性
      • 2.1.2 String常用API
      • 2.1.3 String常見面試題(附參考答案)
    • 2.2 StringBuilder
      • 2.2.1 StringBuilder特性
      • 2.2.2 StringBuilder常用API
      • 2.2.3 StringBuilder常見面試題(附參考答案)
    • 2.3 StringBuffer
      • 2.3.1 StringBuffer特性
      • 2.3.2 StringBuffer常用API
      • 2.3.3 StringBuffer常見面試題(附參考答案)


一、性能測驗

1.1 代碼實作

分別撰寫String、StringBuilder及StringBuffer的JMH基準單元測驗方法:
StringAppendJmhTest.java

package com.justin.java;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.AverageTime) //基準測驗型別:time/ops(每次呼叫的平均時間)
@OutputTimeUnit(TimeUnit.NANOSECONDS) //基準測驗結果的時間型別:微秒
@Warmup(iterations = 5) //預熱:5 輪
@Measurement(iterations = 5) //度量:測驗5輪
@Fork(3) //Fork出3個執行緒來測驗
@State(Scope.Thread) // 每個測驗執行緒分配1個實體
public class StringAppendJmhTest {
    @Param({"2", "10", "100", "1000"})
    private int count; //指定添加元素的不同個數,便于分析結果

    @Setup(Level.Trial) // 初始化方法,在全部Benchmark運行之前進行
    public void init() {
        System.out.println("Start...");
    }

    public static void main(String[] args) throws RunnerException {
        //1、啟動基準測驗:輸出普通檔案
//        Options opt = new OptionsBuilder()
//                .include(ArrayAndLinkedJmhTest.class.getSimpleName()) //要匯入的測驗類
//                .output("C:\\Users\\Administrator\\Desktop\\StringAppendJmhTest.log") //輸出測驗結果的普通txt檔案
//                .build();


        //1、啟動基準測驗:輸出json結果檔案(用于查看可視化圖)
        Options opt = new OptionsBuilder()
                .include(StringAppendJmhTest.class.getSimpleName()) //要匯入的測驗類
                .result("C:\\Users\\Administrator\\Desktop\\StringAppendJmhTest.json") //輸出測驗結果的json檔案
                .resultFormat(ResultFormatType.JSON)//格式化json檔案
                .build();

        //2、執行測驗
        new Runner(opt).run();
    }

    @Benchmark
    public void stringAppendTest(Blackhole blackhole) {
        String str = new String();
        for (int i = 0; i < count; i++) {
            str = str + "Justin";
        }
        blackhole.consume(str);
    }

    @Benchmark
    public void stringBufferAppendTest(Blackhole blackhole) {
        StringBuffer strBuffer = new StringBuffer();
        for (int i = 0; i < count; i++) {
            strBuffer.append("Justin");
        }
        blackhole.consume(strBuffer);
    }

    @Benchmark
    public void stringBuilderAppendTest(Blackhole blackhole) {
        StringBuilder strBuilder = new StringBuilder();
        for (int i = 0; i < count; i++) {
            strBuilder.append("Justin");
        }
        blackhole.consume(strBuilder);
    }

    @TearDown(Level.Trial) // 結束方法,在全部Benchmark運行之后進行
    public void clear() {
        System.out.println("End...");
    }

}

運行main方法進行測驗~

1.2 測驗結果

1.2.1 普通展示

查看控制臺輸出的結果資訊,拉到最后查看最后幾行的Score指標如下:

Benchmark                             (count)  Mode  Cnt       Score       Error  Units
StringAppendJmhTest.stringAppendTest               2  avgt   15      43.029 ±     4.440  ns/op
StringAppendJmhTest.stringAppendTest              10  avgt   15     212.911 ±    22.882  ns/op
StringAppendJmhTest.stringAppendTest             100  avgt   15    9262.168 ±   431.742  ns/op
StringAppendJmhTest.stringAppendTest            1000  avgt   15  830811.924 ± 38227.519  ns/op
StringAppendJmhTest.stringBufferAppendTest         2  avgt   15      35.546 ±     1.159  ns/op
StringAppendJmhTest.stringBufferAppendTest        10  avgt   15     167.670 ±     4.900  ns/op
StringAppendJmhTest.stringBufferAppendTest       100  avgt   15    1698.781 ±    80.934  ns/op
StringAppendJmhTest.stringBufferAppendTest      1000  avgt   15   14059.694 ±   820.273  ns/op
StringAppendJmhTest.stringBuilderAppendTest        2  avgt   15      27.621 ±     1.745  ns/op
StringAppendJmhTest.stringBuilderAppendTest       10  avgt   15     154.621 ±     3.360  ns/op
StringAppendJmhTest.stringBuilderAppendTest      100  avgt   15    1488.514 ±    31.618  ns/op
StringAppendJmhTest.stringBuilderAppendTest     1000  avgt   15   12032.867 ±    69.878  ns/op

示例測驗結果中的Score指標,表示ns/op即平均每次呼叫需要多少微秒,時間越低說明效率越高~

1.2.2 圖形展示

程式運行完成后,會在控制臺輸出結果資訊,還會將結果資訊格式化成json格式保存到了桌面的StringAppendJmhTest.json檔案中,將json檔案通過如下可視化工具生成圖形:

  • JMH Visualizer:https://jmh.morethan.io/
  • JMH Visual Chart:http://deepoove.com/jmh-visual-chart/

測驗結果可視化如下:
在這里插入圖片描述

1.3 結果分析

字串拼接性能:StringBuilder > StringBuffer > String

通過JMH的測驗結果,可以發現在少量拼接字串10個左右,效率區別不大,但是當字串拼接的資料量比較大時,100左右,String比另外兩者效率開始相差好幾倍,當達到1000時,此時String的字串拼接效率真的非常差非常差了,比另外兩者效率低了即幾十上百倍,這種情況應當避免使用String來拼接字串~

二、區別說明

2.1 String

2.1.1 String特性

  • ? 實作了序列化SerializableComparable以及CharSequence字符序列介面
  • ? StringJava字串物件,底層是基于char字符陣列,使用了final修飾類,表示最終類,不能被繼承和修改,執行緒安全~
  • ? 每一次對String宣告的物件的內容進行修改,得到的都是另外一個新的字串常量物件,如果字串常量池中已經存在該字串常量物件,則不會再創建~
  • ? 字串常量JDK1.7之前,存在于方法區運行時常量池中的字串常量池JDK1.7時,字串常量池被移到堆區中,運行時常量池還保留在方法區中
  • ? JDK1.8時,取消了方法區(永久代),方法區被元空間替代,字串常量拼接還被自動優化成了StringBuiler,例如:
    String s1 = “Justin”;
    String s2 = “Jack”;
    String s3 = s1 + s2;
    //javac編譯java源檔案得到Class,再經過javap -c ClassName反編譯查看匯編指令發現,發現s1+s2等價于
    String s4 = new StringBuffer().append(s1).append(s2).toString();
  • ? String重寫了Object類中的equalshashCode方法,重寫后equals方法比較了字串的每一個字符,而重寫hashCode方法則是由字串的每一個字符計算出字串的hashCode值~

2.1.2 String常用API

常用方法方法說明
int length()求字串長度
boolean isEmpty()判斷字串是否為空字串,注意str.isEmpty()呼叫時,要避免strnull
String valueOf(Object obj)轉換Object型別為字串型別
String trim()去除字串兩端的空白
int indexOf(int ch)回傳指定字符在字串中第一次出現的索引,這里的ch指的是char字符對應的ASCII碼值
String replace(char oldChar, char newChar)替換字串中的字符oldCharnewChar
String[] split(String regex)根據regex分割字串,回傳一個分割后的字串陣列
byte[] getBytes()獲取字串的 byte型別陣列
char charAt(int index)獲取指定索引處的字符
String toLowerCase()將字串中的所有大寫字母轉成小寫字母后回傳新的字串,注意原來的字串沒變
String toUpperCase()將字串中的所有小寫字母轉成大寫字母后回傳新的字串,注意原來的字串沒變
String substring(int beginIndex, int endIndex)截取字串,第一位從0開始,包含左邊beginIndex,不包含右邊endIndex
boolean equals(Object anObject)比較字串內容是否相等

以上是比較常用的方法,更多可以查看java.lang.String的原始碼~

2.1.3 String常見面試題(附參考答案)

(1)String重寫equals、hashCode方法有什么用??

  • 不重寫默認是Object中的兩個方法,equals默認進行雙等號判斷,比較的是兩個物件的堆區記憶體地址是否相等,而hashCode則是一個native本地方法,內部會自行計算出一個唯一隨機整數值回傳
  • String都重寫了equalshashCode方法,equals重寫后比較的是字串中的每一個字符,hashCode重寫后則是通過數字31與字串中的每一個字符的ASCII碼值計算得到hashCode
  • 簡單的說String重寫equalshashCode方法的主要目的是為了比較兩個物件的內容是否相同,而不是比較物件的記憶體地址,因為兩個內容一樣的字串,可能記憶體地址是不相同的,不是我們想要的結果,

(2)重寫String中的hashCode方法時,為什么要用31這個數字與字串中的每一個字符的ASCII碼值進行計算?

  • 因為31是數學家們計算得到的一個優選質數(如果一個數只能夠被1和本身整除,不能夠被其他數字整除,這個數就是質數,最小質數是2,其他3,5,7,13,17…31…37…)
    這個優選質數能夠降低哈希演算法的沖突率,而且31能夠被JVM優化為1右移5位后再減去131 * i = (i << 5) - i

(2)new String(“Justin”)創建了幾個物件?

  • 一個或者兩個,使用new實體化,首先肯定會在堆區創建一個新物件,至于new String中指定的字串常量,如果該字串常量在字串常量池中不存在,則會再次創建字串常量池中的物件,一共兩個物件~
  • 需要注意的是字串常量池是從JDK1.7開始,就從JVM的方法區遷移到了堆區中了,不是JDK1.8才遷移,JDK1.8是永久代被取消,同時由元空間取代了方法區~

(3)定義String s1=null,String s2="",String s3 = new String(),String s4=new String("")有什么區別?

  • 主要區別在于null沒有分配記憶體,其他三種都分配了記憶體空間
  • 空字串也屬于字串常量,定義的參考會直接指向字串常量池中的字串,如果字串常量池不存在空字串,則該程序會在字串常量池中創建空字串的物件,
  • new String() 由于使用了new實體化,必然會在堆區創建一個新物件,而new String()底層默認將空字串作為字串物件的值,因此該程序可能創建了1個物件或2個物件
  • 同樣new String("")new String()一樣也是可能創建了1個物件或2個物件~

(3)String、StringBuilder及StringBuffer最大的區別是什么?

  • 最大的區別在于String使用final修飾,表示最終類,不可繼承和修改,執行緒安全
  • 而StringBuilder和StringBuffer都是可修改物件,StringBuffer使用synchronized同步修飾方法,執行緒安全,StringBuilder非執行緒安全~
  • String在JDK1.8時字串常量拼接被自動優化成了StringBuiler
  • 關于字串拼接效率,我個人通過Open JDK基準性能測驗工具JMH對三者的new實體化物件,進行字串的拼接測驗,發現效率始終是:
    StringBuilder > StringBuffer > String
    而且在少量拼接字串10個左右時,三者的拼接效率區別并不大,但是當字串拼接的資料量比較大時,100左右,String比另外兩者效率開始相差好幾倍,當達到1000時,此時String的字串拼接效率真的非常差非常差了,比另外兩者效率低了即幾十上百倍,這種情況應當避免使用String來拼接字串~

2.2 StringBuilder

2.2.1 StringBuilder特性

  • ? 底層繼承了AbstractStringBuilder,實作了SerializableCharSequence介面
  • ? 底層基于char字符陣列,可以修改操作物件,非執行緒安全
  • ? 實體化new StringBuffer()時默認位元組陣列初始化容量大小為16,當容量大于當前位元組陣列容量時會自動進行1倍擴容再加2,每次擴容都會開辟新空間,并且進行新老字符陣列的復制
  • ? 原始碼底層通過呼叫System的一個native本地方法arraycopy實作新老字符陣列的復制,該native方法底層會直接操作記憶體,比一般的for回圈遍歷復制陣列的效率要快很多~
  • ? 如果要操作拼接字串,并且拼接的字串很長,又沒有給StringBuilder指定合適的初始化容量大小,可能會導致底層的字符陣列進行多次擴容,多次申請記憶體空間來完成新老字符陣列的復制,性能開銷比較大~

StringBuilder擴容機制的關鍵原始碼:

//擴容條件:當容量大于當前位元組陣列容量時
if (minimumCapacity - value.length > 0) expandCapacity(minimumCapacity);
...
//擴容多少:會自動進行1倍擴容再加2
int newCapacity = value.length * 2 + 2;
...
//新老字符陣列的復制
value = Arrays.copyOf(value, newCapacity);
...
	public static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        //底層操作記憶體進行復制原字符陣列的元素到新位元組陣列
        System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
        return copy;
    }
    ...
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

2.2.2 StringBuilder常用API

常用方法說明
StringBuilder append(String str)拼接字串
String toString()回傳字串內容
char charAt(int index)獲取指定索引的字符
StringBuilder insert(int offset, String str)在指定位置offset之前插入字串
void setCharAt(int index, char ch)將指定位置index的字符替換為ch
StringBuilder insert(int offset, String str)在指定位置offset之前插入字串
StringBuilder delete(int start, int end洗掉起始位置start(含)到結尾位置end(不含)之間的字串

其他方法請查看java.lang.StringBuilder原始碼詳情~

2.2.3 StringBuilder常見面試題(附參考答案)

(1)講一下StringBuilder的擴容機制?

  • 主要結合StringBuffer特性來回答即可~
  • ? 實體化new StringBuffer()時默認位元組陣列初始化容量大小為16,當容量大于當前位元組陣列容量時會自動進行1倍擴容再加2,每次擴容都會開辟新空間,并且進行新老字符陣列的復制
  • ? 原始碼底層通過呼叫System的一個native本地方法arraycopy實作新老字符陣列的復制,該native方法底層會直接操作記憶體,比一般的for回圈遍歷復制陣列的效率要快很多~
  • ? 如果操作的字串很長,又沒有給StringBuilder指定合適的初始化容量大小,可能會導致底層的字符陣列進行多次擴容,多次申請記憶體空間來完成新老字符陣列的復制,性能開銷比較大~

(2)String、StringBuilder及StringBuffer最大的區別是什么?

  • 同String常見面試問題解答即可~

2.3 StringBuffer

2.3.1 StringBuffer特性

  • ? StringBuffer底層實作與StringBuffer最大的區別在于方法使用了synchronized(自創諧音:星可nice的,哈哈哈)同步修飾,因此是執行緒安全的,StringBuilder非執行緒安全~

2.3.2 StringBuffer常用API

跟StringBuilder常用API一樣,只不過加了synchronized修飾,執行緒安全~

2.3.3 StringBuffer常見面試題(附參考答案)

(1)StringBuffer為什么是執行緒安全的?

  • StringBuffer底層使用synchronized同步修飾方法,因此是執行緒安全的~

(2)為什么StringBuffer使用synchronized修飾方法就能保證執行緒安全?

  • synchronized是一個同步鎖,在Java中每個類物件都可以作為鎖,synchronized同步鎖使用的關鍵在于對誰加鎖~
  • synchronized修飾普通方法synchronized methodA(){//操作},是對當前物件加鎖~
  • synchronized修飾靜態方法static synchronized void methodB(){//操作},是對當前類的class物件(所有此類的物件)加鎖~
  • synchronized修飾代碼塊methodC(obj){synchronized(obj) {//操作}},是對括號中的物件加鎖 ~
  • 因此,使用synchronized修飾方法時,會對方法中的相關物件進行加鎖,如果某個執行緒搶先呼叫了該方法,那么將獨占相關物件的鎖,其他執行緒如果此時呼叫到該方法的相關物件時,會被阻塞~

(3)String、StringBuilder及StringBuffer最大的區別是什么?

  • 最大的區別在于String使用final修飾,表示最終類,不可繼承和修改,執行緒安全
  • 而StringBuilder和StringBuffer都是可修改物件,StringBuffer使用synchronized同步修飾方法,執行緒安全,StringBuilder非執行緒安全~
  • String在JDK1.8時字串常量拼接被自動優化成了StringBuiler
  • 關于字串拼接效率,我個人通過Open JDK基準性能測驗工具JMH對三者的new實體化物件,進行字串的拼接測驗,發現效率始終是:
    StringBuilder > StringBuffer > String
    而且在少量拼接字串10個左右時,三者的拼接效率區別并不大,但是當字串拼接的資料量比較大時,100左右,String比另外兩者效率開始相差好幾倍,當達到1000時,此時String的字串拼接效率真的非常差非常差了,比另外兩者效率低了即幾十上百倍,這種情況應當避免使用String來拼接字串~

好了,本文的String、StringBuilder及StringBuffer區別分析就到這里結束啦,如有不妥和不足的地方,歡迎評論區指出糾正,非常感謝!!

原創不易,覺得有用的小伙伴來個一鍵三連(點贊+收藏+評論 )+關注支持一下,非常感謝~
在這里插入圖片描述

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

標籤:java

上一篇:Java基礎語法筆記

下一篇:編程能力從什么時候開始突飛猛進?小白到大神的必經之路

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