二進(jìn)制數(shù)組

這個(gè)部分如果沒有C語言和計(jì)算機(jī)基礎(chǔ)會(huì)比較難理解,如果實(shí)在理解不了可以收藏它,日后再看。

二進(jìn)制數(shù)組其實(shí)很早就有了,不過為了 WebGL 中,數(shù)據(jù)可以高效和顯卡交換數(shù)據(jù)。分為3類:

  • ArrayBuffer:代表內(nèi)存中的一段二進(jìn)制數(shù)據(jù);
  • TypedArray:讀寫簡單的二進(jìn)制數(shù)據(jù),如 Uint8Array, Int16Array, Float32Array 等9類;
  • DataView:讀寫復(fù)雜的二進(jìn)制數(shù)據(jù),如 Uint8, Int16, Float32 等8類;
數(shù)據(jù)類型 字節(jié)長度 含義 對(duì)應(yīng) C 語言類型 TypedArray 類型 DataView 類型
Int8 1 8位有符號(hào)整數(shù) char Int8Array Int8
Uint8 1 8位無符號(hào)整數(shù) unsigned char Uint8Array Uint8
Uint8C 1 8位無符號(hào)整數(shù)(自動(dòng)過濾溢出) unsigned char Uint8ClampedArray 不支持
Int16 2 16位有符號(hào)整數(shù) short Int16Array Int16
Uint16 2 16位無符號(hào)整數(shù) unsigned short Uint16Array Uint16
Int32 4 32位有符號(hào)整數(shù) int Int32Array Int32
Uint32 4 32位無符號(hào)整數(shù) unsigned int Uint32Array Uint32
Float32 4 32位浮點(diǎn)數(shù) float Float32Array Float32
Float64 8 64位浮點(diǎn)數(shù) double Float64Array Float64

ArrayBuffer

ArrayBuffer 代表內(nèi)存中的一段二進(jìn)制數(shù)據(jù),我們沒法直接操作,需要利用視圖(TypedArray,DataView)按一定格式解讀二進(jìn)制數(shù)據(jù)。但我們依然可以構(gòu)造一段內(nèi)存來存放二進(jìn)制數(shù)據(jù):

var buf = new ArrayBuffer(32);  //分配32個(gè)字節(jié)的內(nèi)存存放數(shù)據(jù), 默認(rèn)全0
var dataview = new DataView(buf);   //將這段內(nèi)存轉(zhuǎn)為視圖
dataview.getUint8(0);   //得到第一個(gè)8字節(jié)的值(無符號(hào)),0

這里需要強(qiáng)調(diào)的是,分配內(nèi)存空間不要太大!畢竟你的內(nèi)存是有限的。
其次,無論使用什么視圖,其實(shí)例化的內(nèi)存如果共享,所有的寫入操作會(huì)修改每一個(gè)視圖,因?yàn)閮?nèi)存共用的:

var buf = new ArrayBuffer(32);
var view16 = new Int16Array(buf);
var viewu8 = new Uint8Array(buf);

console.log(viewu8[0]);   //0
view16[0]=-1;
console.log(viewu8[0]);   //255

這里之所以得到255,是因?yàn)閮?nèi)存共用導(dǎo)致的,但為何不是-1?Int16Array 是有符號(hào)類型的,這樣二進(jìn)制的最高位用作符號(hào)位,負(fù)數(shù)記為1:1000 0000 0000 0001,之后的數(shù)字用移碼存儲(chǔ),得到-1的二進(jìn)制為:1111 1111 1111 1111, 之后利用Uint8Array讀取無符號(hào)的前8位,得到1111 1111這個(gè)計(jì)算為十進(jìn)制為 2^8-1=255。具體關(guān)于數(shù)制轉(zhuǎn)換和反碼補(bǔ)碼這里不再展開,否則就跑偏了。

ArrayBuffer 對(duì)象也有幾個(gè)方法和屬性:

  • byteLength: 得到內(nèi)存區(qū)域的字節(jié)長度
const N = 32;
var buf = new ArrayBuffer(N);
if(buf.byteLength === N){
  //分配成功
} else {
  //分配失敗
}
  • slice(start=0, end=this.byteLength): 分配新內(nèi)存,并把先有內(nèi)存 start 到 end 部分復(fù)制過去,返回這段新內(nèi)存區(qū)域
var buf = new ArrayBuffer(32);
var newBuf = buf.slice(0,3);
  • isView(view): 判斷傳入的 view 是否當(dāng)前 buffer 的視圖,是則返回 true, 否則 false。該方法暫無法使用。
var buf1 = new ArrayBuffer(32);
var buf2 = new ArrayBuffer(32);
var buf1View = new Int8Array(buf1);
var buf2View = new Int8Array(buf2);

buf1.isView(buf1View);   //true
buf1.isView(buf2View);   //false

TypedArray

具有一個(gè)構(gòu)造函數(shù) DataView(), 接受一個(gè)ArrayBuffer參數(shù),視圖化該段內(nèi)存;或接受一個(gè)數(shù)組參數(shù),實(shí)例化該數(shù)組為二進(jìn)制內(nèi)容。得到的值是一個(gè)數(shù)組,可以直接使用[]訪問每個(gè)位置的內(nèi)容,有length屬性。其構(gòu)造函數(shù)有9個(gè):

數(shù)據(jù)類型 字節(jié)長度 含義 對(duì)應(yīng) C 語言類型 TypedArray 類型構(gòu)造函數(shù)
Int8 1 8位有符號(hào)整數(shù) char Int8Array()
Uint8 1 8位無符號(hào)整數(shù) unsigned char Uint8Array()
Uint8C 1 8位無符號(hào)整數(shù)(自動(dòng)過濾溢出) unsigned char Uint8ClampedArray()
Int16 2 16位有符號(hào)整數(shù) short Int16Array()
Uint16 2 16位無符號(hào)整數(shù) unsigned short Uint16Array()
Int32 4 32位有符號(hào)整數(shù) int Int32Array()
Uint32 4 32位無符號(hào)整數(shù) unsigned int Uint32Array()
Float32 4 32位浮點(diǎn)數(shù) float Float32Array()
Float64 8 64位浮點(diǎn)數(shù) double Float64Array()

以上9個(gè)會(huì)對(duì)內(nèi)存進(jìn)行不同位數(shù)的格式化,以得到對(duì)應(yīng)類型值的數(shù)組。這個(gè)數(shù)組不同于普通數(shù)組,它不支持稀疏數(shù)組,默認(rèn)值為0,而且同一個(gè)數(shù)組只能存放同一個(gè)類型的變量。

以上每個(gè)構(gòu)造函數(shù)都對(duì)應(yīng)如下形式的參數(shù):

(buffer, start=0, len=buffer.byteLength-start*8)

可以指定序列化其中 start到 end部分的二進(jìn)制數(shù)據(jù)。注意這里指定的范圍必須和數(shù)組類型所匹配,不能出現(xiàn)類似new Int32Array(buffer,2,2)的情況。如果你覺得這個(gè)不符合你的需求,可以使用 DataView。

如果你覺得上面的寫法復(fù)雜,可以不寫 new ArrayBuffer,直接使用 TypedArray,但注意參數(shù)的意義不一樣:

var f64a = new Float64Array(4);    //分配32個(gè)字節(jié),并作為double類型使用。 32 = 64 / 8 * 4

TypedArray的構(gòu)造函數(shù)還接受另一個(gè)TypedArray作為參數(shù),開辟新內(nèi)存復(fù)制其值并改變類型,對(duì)原視圖和buffer 不構(gòu)成影響,也不共用內(nèi)存。
TypeArray的構(gòu)造函數(shù)還接受另一個(gè)Array作為參數(shù),開辟新內(nèi)存復(fù)制其值,對(duì)原數(shù)組不構(gòu)成影響,也不共用內(nèi)存。

當(dāng)然利用一下方法,可以把 TypedArray 轉(zhuǎn)換為普通數(shù)組:

var arr = [].slice.call(typedArray);

TypedArray具有除了concat()以外的全部數(shù)組方法,當(dāng)然,它也具有 iterator,可以用 for...of 遍歷。
以下是 TypedArray 特有的屬性和方法:

  • buffer屬性:返回該視圖對(duì)于的二進(jìn)制內(nèi)存區(qū)域
  • BYTES_PER_ELEMENT屬性:是個(gè)常數(shù),表示數(shù)組中每個(gè)值的字節(jié)大小,不同視圖的返回值與上方表格一致
  • byteLength: 返回該視圖對(duì)于的內(nèi)存大小,只讀
  • byteOffset: 返回該視圖從對(duì)應(yīng) buffer 的哪個(gè)字節(jié)開始,只讀
  • set(arr_or_typeArray, start=0): 在內(nèi)存層面,從arr_or_typeArray 的 start 下標(biāo)開始復(fù)制數(shù)組到當(dāng)然 typeArray
  • subarray(start=0,end=this.length),截取 start到 end部分子數(shù)組,但是和原數(shù)組共用內(nèi)存
  • from(): 接受一個(gè)可遍歷參數(shù),轉(zhuǎn)為該視圖實(shí)例
  • of(): 將參數(shù)列表轉(zhuǎn)為該視圖實(shí)例

小技巧,轉(zhuǎn)換字符串和 ArrayBuffer

//該方法僅限轉(zhuǎn)換 utf-16 的字符串
function ab2str(buf){
  return String.fromCharCode.apply(null, new Uint16Array(buf));
}
function str2ab(str){
  var len = str.length;
  var view = new Uint16Array(len);
  for(let i = 0; i < len; i++){
    view[i] = str.charCodeAt(i);
  }
  return view.buffer;
}
var str = "Hello world";
var buf = str2ab(str);
var view = new Uint16Array(buf);
for(var i = 0; i < view.length; i++){
  console.log(String.fromCharCode(view[i]));   //一次輸出"Hello world"的每個(gè)字母
}
console.log(ab2str(buf));    //"Hello world"

這里擴(kuò)展一些編碼知識(shí),我們知道計(jì)算機(jī)里面存儲(chǔ)的是二進(jìn)制,并且存儲(chǔ)的最小單位是字節(jié)。但是不同的系統(tǒng)存儲(chǔ)方式不同,分為高位優(yōu)先和低位優(yōu)先。比如 20170101 這個(gè)數(shù)字,其十六進(jìn)制表示為 0x0133C575, 在低位優(yōu)先的系統(tǒng)中存儲(chǔ)方式為 0x75 0xC5 0x33 0x01, 而在高位優(yōu)先的系統(tǒng)中存儲(chǔ)方式為 0x01 0x33 0xC5 0x75。由于大多數(shù)計(jì)算機(jī)采用低位優(yōu)先的方式,所以 ES6 采用是也是低位優(yōu)先的方式,但遇到高位優(yōu)先的數(shù)據(jù)時(shí),就不能簡單的直接那來使用,具體使用會(huì)在 DataView 中介紹,這里說明一種判斷低位優(yōu)先(little endian)還是高位優(yōu)先(big endian)的方法:

還有需要注意的是數(shù)據(jù)溢出,這個(gè)也是需要數(shù)制方面基礎(chǔ)比較好理解,這里不過多展開了。舉一個(gè)例子:
Uint8 只能表示8位無符號(hào)整數(shù),最大是1111 1111, 也就是十進(jìn)制的 0~255;Int8因?yàn)橛辛朔?hào)位,只能表示十進(jìn)制-128~127,如果給它的值不在這個(gè)范圍內(nèi)就會(huì)發(fā)生溢出,得到一個(gè)你意想不到但情理之中的值

var view1 = new Uint8Array(2);
view1[0] = 256;   //256 二進(jìn)制是 1 0000 0000 由于數(shù)據(jù)只能容納8個(gè)值,進(jìn)位1就丟了
view1[1] = -1;    //之前說過-1 二進(jìn)制(補(bǔ)碼)為 1111 1111(全1), 作為無符號(hào)數(shù)8個(gè)1就是255

console.log(view1[0]);   //0
console.log(view1[1]);   //255

var view2 = new Int8Array(2);
view2[0] = 128;   //由于符號(hào)位溢出,系統(tǒng)自動(dòng)用32位計(jì)算這個(gè)數(shù)1 000 0000 0000 0000 0000 0000 1000 0000,取符號(hào)位和最后8位得到-128
view2[1] = -128;  //由于符號(hào)位溢出,系統(tǒng)自動(dòng)用32位計(jì)算這個(gè)數(shù)0 111 1111 1111 1111 1111 1111 0111 1111,取符號(hào)位和最后8位得到127
console.log(view2[0]);   //-128
console.log(view2[1]);   //127

為了防止這樣的情況,js 有一個(gè) Unit8ClampedArray, 使整數(shù)方向的溢出值為255,0方向的易楚志為0。注意這是個(gè)無符號(hào)的類型;

var view = new Uint8ClampedArray(2);
view[0] = 256;
view[1] = -1;

console.log(view[0]);   //255
console.log(view[1]);   //0

復(fù)合視圖

劃分一塊 buffer 使用得到 C 語言中的結(jié)構(gòu)體

var buf = new ArrayBuffer(24);
var name = new Uint8Array(buf, 0, 16);
var gender = new Uint8Array(buf, 16, 1);
var age = new Uint16Array(buf, 18, 1);
var score = new Float32Array(buf,20,1);

相當(dāng)于以下 C語言代碼

struct Person{
  char name[16];
  char gender;
  int age;
  float score;
}

共用一塊 buffer 使用得到 C 語言中的聯(lián)合體

var buf = new ArrayBuffer(8);
var num = new Uint16Array(buf);
var dotNum = new Float64Array(buf);

相當(dāng)于以下 C語言代碼

union Example{
  int num[4];
  double dotNum;
}

DataView

具有一個(gè)構(gòu)造函數(shù) DataView(), 接受一個(gè)ArrayBuffer參數(shù),視圖化該段內(nèi)存。畢竟當(dāng)一段內(nèi)存有多種數(shù)據(jù)時(shí),復(fù)合視圖也不是那么方便,這時(shí)適合使用 DataView 視圖。其次 DataView 可以自定義高位優(yōu)先和低位優(yōu)先,這樣可以讀取的數(shù)據(jù)就更多了。
DataView構(gòu)造函數(shù)形式如下,這一點(diǎn)和 TypedArray 一致:

(buffer, start=0, len=buffer.byteLength-start*8)

它具有以下方法格式化讀取 buffer 中的信息:

  • getInt8(start, isLittleEndian): 從 start 字節(jié)處讀取 1 個(gè)字節(jié),返回一個(gè)8位有符號(hào)整數(shù), 第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • getUint8(start, isLittleEndian): 從 start 字節(jié)處讀取 1 個(gè)字節(jié),返回一個(gè)8位無符號(hào)整數(shù), 第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • getInt16(start, isLittleEndian): 從 start 字節(jié)處讀取 2 個(gè)字節(jié),返回一個(gè)16位有符號(hào)整數(shù), 第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • getUint16(start, isLittleEndian): 從 start 字節(jié)處讀取 2 個(gè)字節(jié),返回一個(gè)16位無符號(hào)整數(shù), 第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • getInt32(start, isLittleEndian): 從 start 字節(jié)處讀取 4 個(gè)字節(jié),返回一個(gè)32位有符號(hào)整數(shù), 第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • getUint32(start, isLittleEndian): 從 start 字節(jié)處讀取 4 個(gè)字節(jié),返回一個(gè)32位無符號(hào)整數(shù), 第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • getFloat32(start, isLittleEndian): 從 start 字節(jié)處讀取 4 個(gè)字節(jié),返回一個(gè)32位浮點(diǎn)數(shù), 第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • getFloat64(start, isLittleEndian): 從 start 字節(jié)處讀取 8 個(gè)字節(jié),返回一個(gè)64位浮點(diǎn)數(shù), 第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;

它具有以下方法格式化寫入 buffer 中的信息:

  • setInt8(start,value,isLittleEndian): 在 start位置寫入 1 個(gè)字節(jié)的8位有符號(hào)整數(shù)value;第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • setUint8(start,value,isLittleEndian): 在 start位置寫入 1 個(gè)字節(jié)的8位無符號(hào)整數(shù)value;第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • setInt16(start,value,isLittleEndian): 在 start位置寫入 2 個(gè)字節(jié)的16位有符號(hào)整數(shù)value;第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • setUint16(start,value,isLittleEndian): 在 start位置寫入 2 個(gè)字節(jié)的16位無符號(hào)整數(shù)value;第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • setInt32(start,value,isLittleEndian): 在 start位置寫入 4 個(gè)字節(jié)的32位有符號(hào)整數(shù)value;第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • setUint32(start,value,isLittleEndian): 在 start位置寫入 4 個(gè)字節(jié)的32位無符號(hào)整數(shù)value;第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • setFloat32(start,value,isLittleEndian): 在 start位置寫入 4 個(gè)字節(jié)的32位浮點(diǎn)數(shù)value;第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;
  • setFloat64(start,value,isLittleEndian): 在 start位置寫入 8 個(gè)字節(jié)的64位浮點(diǎn)數(shù)value;第二參默認(rèn)為 false 表示使用高位優(yōu)先,為 true 表示低位優(yōu)先;

它具有以下屬性和方法:

  • buffer屬性:返回該視圖對(duì)于的二進(jìn)制內(nèi)存區(qū)域
  • byteLength: 返回該視圖對(duì)于的內(nèi)存大小,只讀
  • byteOffset: 返回該視圖從對(duì)應(yīng) buffer 的哪個(gè)字節(jié)開始,只讀

如果你不知道計(jì)算機(jī)使用的是高位優(yōu)先還是低位優(yōu)先,也可以自行判斷:

//方法1
const BIG_ENDIAN = Symbol('BIG_ENDIAN');
const LITTLE_ENDIAN = Symbol('LITTLE_ENDIAN');
function getPlatformEndianness(){
  let arr32 =  Uint32Array.of(0x12345678);
  let arr8 = new Uint8Array(arr32.buffer);
  switch((arr8[0]*0x1000000)+(arr8[1]*0x10000)+(arr8[2]*0x100)+arr8[3]){
    case 0x12345678: return BIG_ENDIAN;
    case 0x78563412: return LITTLE_ENDIAN;
    default: throw new Error("unknow Endianness");
  }
}

//方法2
window.isLittleEndian = (function(){
  var buffer = new ArrayBuffer(2);
  new DataView(buffer).setInt16(0, 256, true);
  return new Int16Array(buffer)[0] === 256;
}());
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,214評(píng)論 3 426
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,315評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,699評(píng)論 1 327
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,882評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,441評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,189評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,388評(píng)論 1 372
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,613評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評(píng)論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,112評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,334評(píng)論 2 377

推薦閱讀更多精彩內(nèi)容

  • 二進(jìn)制數(shù)組(ArrayBuffer對(duì)象、TypedArray視圖和DataView視圖)是JavaScript操作...
    呼呼哥閱讀 21,353評(píng)論 2 12
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,816評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,733評(píng)論 18 399
  • 既然愛情是亙古不變的主題,那我就說說幾個(gè)朋友的愛情故事。 一 和尚,90后,山東大漢,熱血青年,最初相識(shí)在一個(gè)qq...
    魚小婧閱讀 562評(píng)論 3 1
  • 姓名:陳權(quán) 公司:青檸養(yǎng)車 【知~學(xué)習(xí)】 《六項(xiàng)精進(jìn)》大綱56遍 共89遍 《活法貳》音頻打卡第5天 《輕課口語》...
    水青檸閱讀 173評(píng)論 0 0