博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
x265-1.7版本-common/lowres.h注释
阅读量:2189 次
发布时间:2019-05-02

本文共 18257 字,大约阅读时间需要 60 分钟。

注:问号以及未注释部分 会在x265-1.8版本内更新 

/***************************************************************************** * Copyright (C) 2013 x265 project * * Authors: Gopu Govindaswamy 
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. * * This program is also available under a commercial proprietary license. * For more information, contact us at license @ x265.com. *****************************************************************************/#ifndef X265_LOWRES_H#define X265_LOWRES_H#include "primitives.h"#include "common.h"#include "picyuv.h"#include "mv.h"namespace x265 {// private namespacestruct ReferencePlanes{ ReferencePlanes() { memset(this, 0, sizeof(ReferencePlanes)); }//初始化 pixel* fpelPlane[3]; //只是指针 如果是isLowres,则fpePlane[0] = lowresPlane[0] 如果是原始分辨率:分别为重构帧YUV的值 加权 指向加权帧位置 pixel* lowresPlane[4];//是4个指针,分别指向子类Lowres中buffer[4]的4个下采样亮度数据 用于分像素预测 PicYuv* reconPic; //只在原始分辨率中使用,指向重构帧 bool isWeighted; //在原分辨率中:表示是否加权 LookaheadTLD weightedRef中:初始化为false,表示是否加权 bool isLowres; // 该帧是否是Low resolution,即下采样后的帧。isLowres标志只在Lowres::create()函数中才会被设置为true,其他情况均为false(构造函数ReferencePlanes()默认初始化为false) intptr_t lumaStride; //当前步长信息,如果是lowres 则 width + 2 * origPic->m_lumaMarginX; 不足32补足32 // 如宽度为416, width = 416/2 = 208 208+ 2*96 =400 二进制:110010000 // 后五位有数据,向上取整32 400+16 = 416 110100000 // 如果为原始分辨率:则为重构帧的亮度步长 intptr_t chromaStride;//只在原始分辨率中使用:为色度步长 struct { int weight;//权重系数 整个的权重系数等于:(1<<(7-shift)) + weight 目前的权重系数为guessScale * (1<
m_cuOffsetY[ctuAddr] + reconPic->m_buOffsetY[absPartIdx]; } pixel* getCbAddr(uint32_t ctuAddr, uint32_t absPartIdx) { return fpelPlane[1] + reconPic->m_cuOffsetC[ctuAddr] + reconPic->m_buOffsetC[absPartIdx]; } pixel* getCrAddr(uint32_t ctuAddr, uint32_t absPartIdx) { return fpelPlane[2] + reconPic->m_cuOffsetC[ctuAddr] + reconPic->m_buOffsetC[absPartIdx]; } /* lowres motion compensation, you must provide a buffer and stride for QPEL averaged pixels * in case QPEL is required. Else it returns a pointer to the HPEL pixels */ /** 函数功能 : 获取当前qmv下的参考考数据块(分像素作伪插值操作) /* 调用范围 : 只CostEstimateGroup::estimateCUCost和void mcLuma函数中被调用 * \参数blockOffset: 当前块的位置 * \参数 qmv: 其中一个mvc * \参数 buf: 存储1/4分像素插值数据 * \参数 outstride: 更新当前步长 * \返回 : 参考块数据 */ inline pixel *lowresMC(intptr_t blockOffset, const MV& qmv, pixel *buf, intptr_t& outstride) { /* 例如当前4块参考帧(同一参考帧,不同采样方法) 87 94 101 98 97 96 105 102 103 93 102 104 104 122 127 130 132 135 119 106 153 148 141 151 148 147 146 136 136 82 126 122 132 138 146 140 133 130 76 43 62 66 62 56 102 70 90 68 53 45 63 74 61 108 62 74 68 51 45 40 82 94 54 94 63 61 50 48 42 41 83 74 71 78 65 50 51 45 39 36 64 52 89 80 53 50 47 44 39 33 47 57 66 60 49 51 47 45 37 35 91 99 98 99 94 103 101 105 98 93 103 107 109 127 126 132 134 133 105 113 152 152 144 148 147 145 147 131 119 50 121 125 140 135 151 137 126 117 47 42 63 64 58 85 75 84 85 58 46 42 71 74 67 99 59 84 55 47 44 35 90 79 72 74 66 54 49 45 42 38 87 70 69 78 56 49 49 40 39 33 59 62 96 65 48 49 46 42 35 34 49 66 65 51 50 50 45 42 35 37 92 100 107 119 119 119 120 120 107 80 125 123 118 127 127 129 131 132 116 118 164 156 154 162 165 164 155 149 126 46 71 77 81 82 118 90 100 90 56 45 65 70 68 77 82 78 86 56 46 43 70 87 53 111 59 66 55 49 46 40 86 87 57 85 66 55 49 47 39 39 79 61 94 81 60 49 49 45 40 34 48 51 67 71 50 50 47 43 37 33 50 65 81 51 49 51 49 45 36 35 96 105 110 122 116 122 120 116 92 86 126 124 120 128 125 130 134 123 119 93 157 160 160 161 166 161 149 151 74 43 72 77 87 88 114 92 99 72 50 42 67 70 59 102 57 97 70 50 43 38 82 79 74 84 65 63 50 48 44 38 95 72 64 79 62 50 49 42 40 34 72 70 95 72 50 49 48 42 37 33 51 56 75 58 49 49 44 42 33 36 51 82 65 47 51 51 47 40 36 35 **/ if ((qmv.x | qmv.y) & 1) //如果当前需要 1/4 分像素插值 { //将分像素MV倒数第二位获取一个插值buf数据 倒数第一位获取一个插值buf数据 假设当前分像素MV为(3,1) int hpelA = (qmv.y & 2) | ((qmv.x & 2) >> 1); pixel *frefA = lowresPlane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride; //3,1 (x:0x11,y:0x01) 取倒数第二位(x:0x1x,y:0x0x)得到插值buf (yx:01) /* 如当前分像素MV为(3,1) 返回的是buf1的数据 91 99 98 99 94 103 101 105 103 107 109 127 126 132 134 133 152 152 144 148 147 145 147 131 121 125 140 135 151 137 126 117 63 64 58 85 75 84 85 58 71 74 67 99 59 84 55 47 90 79 72 74 66 54 49 45 87 70 69 78 56 49 49 40 **/ int qmvx = qmv.x + (qmv.x & 1); int qmvy = qmv.y + (qmv.y & 1); int hpelB = (qmvy & 2) | ((qmvx & 2) >> 1); //将分像素倒数第二位四舍五入取整,获取一个新的MV (4,2), 当前分像素mv(0,2) pixel *frefB = lowresPlane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * lumaStride;//3,1 (x:00,y:10) 取倒数第二位(x:0x,y:1x)得到插值buf (yx:10) /* 如当前分像素MV为(3,1) 返回的是buf2的数据 (当前整像素MV(1,0)) 100 107 119 119 119 120 120 107 80 123 118 127 127 129 131 132 116 118 156 154 162 165 164 155 149 126 46 77 81 82 118 90 100 90 56 45 70 68 77 82 78 86 56 46 43 87 53 111 59 66 55 49 46 40 87 57 85 66 55 49 47 39 39 61 94 81 60 49 49 45 40 34 51 67 71 50 50 47 43 37 33 65 81 51 49 51 49 45 36 35 **/ primitives.pu[LUMA_8x8].pixelavg_pp(buf, outstride, frefA, lumaStride, frefB, lumaStride, 32);//获取两块的平均值dst[x] = (src0[x] + src1[x] + 1) >> 1; /* 如当前分像素MV为(3,1) 返回的是 96 103 109 109 107 112 111 106 113 113 118 127 128 132 133 125 154 153 153 157 156 150 148 129 99 103 111 127 121 119 108 87 67 66 68 84 77 85 71 52 79 64 89 79 63 70 52 47 89 68 79 70 61 52 48 42 74 82 75 69 53 49 47 40 **/ return buf; } else { outstride = lumaStride; //更新实际的stride int hpel = (qmv.y & 2) | ((qmv.x & 2) >> 1); //选择参考帧buf(4份)位置:当前qmv.x 和qmv.y的后两位只可能是:00或者10 取y的倒数第二位为当前第一位 取x的倒数第二位当前第二位 组合:00 01 10 11 即:0,1,2,3 /* 如当前分像素MV为(2,2) 返回的是采样3的buf 96 105 110 122 116 122 120 116 126 124 120 128 125 130 134 123 157 160 160 161 166 161 149 151 72 77 87 88 114 92 99 72 67 70 59 102 57 97 70 50 82 79 74 84 65 63 50 48 95 72 64 79 62 50 49 42 72 70 95 72 50 49 48 42 **/ return lowresPlane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride;//返回参考块首地址 } } /** 函数功能 : 函数功能相对于lowresMC函数基本一致,其返还的结果是sad或者satd值:获取伪分像素插值的sad值或者satd值 /* 调用范围 : 只MotionEstimate::motionEstimate函数中被调用 * \参数 fenc: 编码块首地址 * \参数blockOffset: 当前块的位置 * \参数 qmv: 其中一个mvc * \参数 comp: 用于计算sad或者satd的函数指针 * \返回 : 伪分像素插值的sad值或者satd值*/ inline int lowresQPelCost(pixel *fenc, intptr_t blockOffset, const MV& qmv, pixelcmp_t comp) { if ((qmv.x | qmv.y) & 1) //如果当前需要 1/4 分像素插值 { ALIGN_VAR_16(pixel, subpelbuf[8 * 8]); //存储1/4分像素插值数据 int hpelA = (qmv.y & 2) | ((qmv.x & 2) >> 1); pixel *frefA = lowresPlane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride; int qmvx = qmv.x + (qmv.x & 1); int qmvy = qmv.y + (qmv.y & 1); int hpelB = (qmvy & 2) | ((qmvx & 2) >> 1); pixel *frefB = lowresPlane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * lumaStride; primitives.pu[LUMA_8x8].pixelavg_pp(subpelbuf, 8, frefA, lumaStride, frefB, lumaStride, 32); return comp(fenc, FENC_STRIDE, subpelbuf, 8); //获取伪分像素插值的sad值或者satd值 } else { int hpel = (qmv.y & 2) | ((qmv.x & 2) >> 1); pixel *fref = lowresPlane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride; return comp(fenc, FENC_STRIDE, fref, lumaStride); //获取伪分像素插值的sad值或者satd值 } }};/* lowres buffers, sizes and strides */struct Lowres : public ReferencePlanes{ pixel *buffer[4]; //这里需要申请4个buffer ,因为将要通过4 hpel下采样得到4份1/2亮度 用于分像素预测 /* 查看 非asm函数frame_init_lowres_core 这样做的目的是更好的通过1/2下采样视频的编码估计原始视频编码状态 将亮度分四种方法进行1/2下采样 原始点: 82 89 86 86 93 85 89 99 101 113 96 97 97 100 104 106 108 107 111 109 127 156 133 139 137 0: 在行列选择偶数像素点为基准并选择相邻的右边、下边、右下机本身4个点作平均 * * + + * * + + - - # # - - # # 87 94 102 104 87 = ((((82 + 85 + 1) >> 1) + ((89 + 89 + 1) >> 1) + 1) >> 1) 94 = ((((86 + 99 + 1) >> 1) + ((86 + 101 + 1) >> 1) + 1) >> 1) 102= ((((96 + 106 + 1) >> 1) + ((97 + 108 + 1) >> 1) + 1) >> 1) 104 = ((((97 + 107 + 1) >> 1) + ((100 + 111 + 1) >> 1) + 1) >> 1) h: 在行选择偶数像素点,在列选择奇数像素点为基准并选择相邻的右边、下边、右下机本身4个点作平均 = * * = + + = * * = + + = - - = # # = - - = # # 91 99 103 107 91 = ((((89 + 89 + 1) >> 1) + ((86 + 99 + 1) >> 1) + 1) >> 1) 99 = ((((86 + 101 + 1) >> 1) + ((93 + 113 + 1) >> 1) + 1) >> 1) v: 在行选择奇数像素点,在列选择偶数像素点为基准并选择相邻的右边、下边、右下机本身4个点作平均 = = = = * * + + * * + + = = = = - - # # - - # # 92 100 125 123 92 = ((((85 + 96 + 1) >> 1) + ((89 + 97 + 1) >> 1) + 1) >> 1) 在行列选择奇数像素点为基准并选择相邻的右边、下边、右下机本身4个点作平均 = = = = = = = * * = + + = * * = + + = = = = = = = - - = # # = - - = # # 96 105 126 124 96 = ((((89 + 97 + 1) >> 1) + ((99 + 97 + 1) >> 1) + 1) >> 1) **/ int frameNum; // Presentation frame number 对应于未下采样原始帧的帧号poc int sliceType; // Slice type decided by lookahead 当前帧的帧类型 //#define X265_TYPE_AUTO 0x0000 /* Let x265 choose the right type */ //#define X265_TYPE_IDR 0x0001 //#define X265_TYPE_I 0x0002 //#define X265_TYPE_P 0x0003 //#define X265_TYPE_BREF 0x0004 /* Non-disposable B-frame */ //#define X265_TYPE_B 0x0005 int width; // width of lowres frame in pixels 真实图像宽度/2 不够一个8x8的 补全8x8一个low CU int lines; // height of lowres frame in pixel lines 真实图像高度/2不够一个8x8的 补全8x8一个low CU int leadingBframes; // 当前帧前面有几个B\b帧(当前GOP下) number of leading B frames for P or I bool bScenecut; // 当前是否是场景切换帧,初始化为trueSet to false if the frame cannot possibly be part of a real scenecut. bool bKeyframe; // 标记当前帧是否为IDR帧 初始化为false bool bLastMiniGopBFrame;//标记当前帧是否为当前GOP的最后一个B帧, 初始化为 false /* lookahead output data */ //第一维表示当前帧号poc-前向参考帧号poc 第二维表示后向参考帧号poc-当前帧号poc int64_t costEst[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]; //[0][0]存储当前lowres中除边界块的全部intra8x8的SATD的累加和(SATD+5+4),其它存储相应帧之间的最优(SATD+mvcost+4)的累加和 B帧的cost会调整 score * 100 / (130 + param->bFrameBias) 开始全部初始化为-1 int64_t costEstAq[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]; //用于自适应量化:[0][0]存储当前lowres中除边界块的全部intra8x8的(SATD+5+4)乘以invQscaleFactor>>8后的累加和 其它存储相应帧之间的最优(SATD+mvcost+4)乘以invQscaleFactor>>8后的累加和 ,开始全部初始化为-1 int32_t* rowSatds[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]; //存储空间中第三维度为lowres中有多少8x8块行, 其中[0][0][cuY]存储当前行的intra (SATD+5+4)值(经过fenc.invQscaleFactor>>8[cuXY]加权), //其它存储相应帧之间的(SATD+mvcost+4)值(经过fenc.invQscaleFactor[cuXY]>>8加权) 第三维第一个数据初始化为-1 int intraMbs[X265_BFRAME_MAX + 2]; //维度表示当前帧号poc - 前向参考帧号poc:存储一帧中的除边界外intra块最优个数(如果有bi模式,并没有比较intra) 初始化为0 int32_t* intraCost; //存储空间为lowres中有多少8x8块 存储对应8x8块的最优intra (SATD+5+4)值 uint8_t* intraMode; //存储空间为lowres中有多少8x8块 存储对应8x8块的最优模式 int64_t satdCost; //获取当前的framecost 如果需要参考帧,取参考帧列表中各自第一帧当做参考帧的framecost 在Lookahead::getEstimatedPictureCost获取值在RateControl::rateControlStart应用 uint16_t* lowresCostForRc;//一个指针,指在vbv应用时用到,指向下面lowresCosts的一帧(跟上面的satdCost一样,只是分开到每个8x8块) 在Lookahead::getEstimatedPictureCost获取指针值(如果自适应量化重新更新cost的加权值) 在FrameEncoder::processRowEncoder应用 //第一维表示当前帧号poc-前向参考帧号poc 第二维表示后向参考帧号poc-当前帧号poc 其中每个值都 | listused <<14 可以检测高14位的数字:0 表示 intra 1 表示前向搜索 2表示后向搜索 3 表示bi搜索 uint16_t(*lowresCosts[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]);//存储空间中第三维度为lowres中有多少8x8块,其中[0][0][cuxy] 存储对应8x8块的最优intra (SATD+5+4)值 其它存储相应(SATD+mvcost+4)或者intra(SATD+5+4)最优值 //第一维表示前向帧还是后向帧,第二维用于标记当前list下的前向/后向第几帧 (如:当前poc = 3 则fenc->lowresMvs[0][0] 表示前向第一帧 poc=2 fenc->lowresMvs[1][1] 表示后向第二帧 poc=5 ) int32_t* lowresMvCosts[2][X265_BFRAME_MAX + 1]; //存储空间中第三维度为lowres中有多少8x8块, 每个8x8存储着相应最优mv对应的satd + mvcost MV* lowresMvs[2][X265_BFRAME_MAX + 1]; //[list][bframe] 存储空间中第三维度为lowres中有多少8x8块 并 将每一帧第一个8x8的mv.x 初始化为0x7FFF 每个8x8存储着相应mv信息 /* used for vbvLookahead */ /************************************************************************/ /* 只存储到第一个GOP中:plannedType、plannedSatd、indB(用于计数) /* 例如当前列表:PbbbPbbbPbbbP 出来之后变为:PbBbPbBbPbBbP /* 第一个GOP(PbbbP) 存储了当前所有的framecost /* 进行标号:P0b1b2b3P4b5b6b7P8b9b10b11P12 /* P0: 无任何存储 /* b1:b3 P8 b5 b6 b7 P12 b9 b10 b11 /* b2:b1 b3 P8 b5 b6 b7 P12 b9 b10 b11 /* b3:P8 b5 b6 b7 P12 b9 b10 b11 /* P4:b1 b2 b3 P8 b5 b6 b7 P12 b9 b10 b11 /************************************************************************/ int plannedType[X265_LOOKAHEAD_MAX + 1];//当前GOP的后向非B帧,用于存储lookachead下的所有帧类型 int64_t plannedSatd[X265_LOOKAHEAD_MAX + 1];//当前GOP的后向非B帧,用于存储lookachead下的所有frame cost int indB;//计数当前存储的framecost 的个数 初始化为0 int bframes;// 等于配置的 param->bframes; 最大连续的B帧个数 /*calcAdaptiveQuantFrame 计算 假设原始帧亮度16x16块的方差标记为 sY 像素个数nY = 16x16 =256 AC能量记为: acY = nY*sY 假设原始帧色度 8x8 块的方差标记为 sCr、sCb 像素个数nC = 8x8 =64 AC能量记为: acCb = nC*sCb acCr = nC*sCr 当前块的AC能量记为:ac = acY + acCb + acCr 每个16x16块按照光栅扫描记为 ac(i) , 总共个数为n 当前所有块的平均值为 AveAc = (Σ((ac+1)^0.1))/n 当前所有块的平方和均值为 AveAc2 = (Σ((ac+1)^0.2))/n 当前自适应量化的强度记为:strength 当前的位宽为 depth 如果:param->rc.aqMode = X265_AQ_NONE qpAqOffset [i] = 0 qpCuTreeOffset [i] = 0 invQscaleFactor[i] = 256 (即权重系数为1 因为真正的权重为 invQscaleFactor[i]>>8) 如果:param->rc.aqMode = X265_AQ_VARIANCE strength = param->rc.aqStrength * 1.0397f; qp_adj = strength * (log2(ac(i)) - (14.427 + 2*(depth-8)))) qpAqOffset [i] = qp_adj qpCuTreeOffset [i] = qp_adj invQscaleFactor[i] = x265_exp2fix8(qp_adj) 如果:param->rc.aqMode = X265_AQ_AUTO_VARIANCE strength = param->rc.aqStrength * Σ((ac+1)^0.1)/√( 2^depth-8)); qp_adj = strength * ((ac(i)+1)^0.1 - AveAc - 0.5*(AveAc2-11.0*(√( 2^depth-8))))/AveAc) qpAqOffset [i] = qp_adj qpCuTreeOffset [i] = qp_adj invQscaleFactor[i] = x265_exp2fix8(qp_adj) **/ double* qpAqOffset; // AQ QP offset values for each 16x16 CU /* 用处? 空间大小:一帧中16x16块的个数 如果是1pass 或者非参考帧 在calcAdaptiveQuantFrame中计算,如果是2pass 从1pass文件中直接读取 **/ double* qpCuTreeOffset; // cuTree QP offset values for each 16x16 CU /* 用处? 空间大小:一帧中16x16块的个数 如果是1pass 或者非参考帧 在calcAdaptiveQuantFrame中计算 cuTreeFinish计算,如果是2pass 从1pass文件中直接读取 ?????? **/ int* invQscaleFactor; // qScale values for qp Aq Offsets /* 用处? 空间大小:一帧中16x16块的个数 如果是1pass 或者非参考帧 在calcAdaptiveQuantFrame中计算,如果是2pass 从1pass文件中直接读取 **/ uint64_t wp_ssd[3]; // This is different than SSDY, this is sum(pixel^2) - sum(pixel)^2 for entire frame //存储一整原始帧的AC能量(约等于 n倍的方差 n为图像像素个数) 0,1,2 分别表示Y、U、V 数据在calcAdaptiveQuantFrame函数计算 //Σ(x^2) - (Σx * Σx)/n = n*Variance (n倍的方差) (含补全8x8块)边像素值 uint64_t wp_sum[3]; //存储未下采样原始帧所有像素的和(Σx) 0,1,2 分别表示Y、U、V 在calcAdaptiveQuantFrame函数计算 (含补全8x8块)边像素值 /* cutree intermediate data */ uint16_t* propagateCost; //存储空间为lowres中有多少8x8块 存储每个8x8块的传播cost(累加传播cost + 加权intracost)*(intracost-最优cost)/intracost 用于计算可参考帧的qpCuTreeOffset值 double weightedCostDelta[X265_BFRAME_MAX + 2]; //如果weightsAnalyse中判断加权优存储参考帧(是下采样后的原始帧)加权的SATD/不加权的SATD,否则存储0 坐标为当前帧poc-参考帧poc ,初始化为0 /** 函数功能 : 初始化数据,并申请空间内存 /* 调用范围 : 只Frame::create函数中被调用 * \参数 origPic: Frame.m_fencPic 原始帧YUV数据 * \返回 : 是否申请内存成功 */ bool create(PicYuv *origPic, int _bframes, bool bAqEnabled); /** 函数功能 : 释放空间内存 /* 调用范围 : 只Frame::destroy函数中被调用 * \返回 : null */ void destroy(); /** 函数功能 : 初始化信息,并进行下采样和扩边 /* 调用范围 : 只void PreLookaheadGroup::processTasks函数中被调用 * \返回 : null */ void init(PicYuv *origPic, int poc);};}#endif // ifndef X265_LOWRES_H

转载地址:http://gauub.baihongyu.com/

你可能感兴趣的文章
【雅思】雅思需要购买和准备的学习资料
查看>>
【雅思】雅思写作作业(1)
查看>>
【雅思】【大作文】【审题作业】关于同不同意的审题作业(重点)
查看>>
【Loadrunner】通过loadrunner录制时候有事件但是白页无法出来登录页怎么办?
查看>>
【English】【托业】【四六级】写译高频词汇
查看>>
【托业】【新东方全真模拟】01~02-----P5~6
查看>>
【托业】【新东方全真模拟】03~04-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST05~06-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST09~10-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST07~08-----P5~6
查看>>
solver及其配置
查看>>
JAVA多线程之volatile 与 synchronized 的比较
查看>>
Java集合框架知识梳理
查看>>
笔试题(一)—— java基础
查看>>
Redis学习笔记(三)—— 使用redis客户端连接windows和linux下的redis并解决无法连接redis的问题
查看>>
Intellij IDEA使用(一)—— 安装Intellij IDEA(ideaIU-2017.2.3)并完成Intellij IDEA的简单配置
查看>>
Intellij IDEA使用(二)—— 在Intellij IDEA中配置JDK(SDK)
查看>>
Intellij IDEA使用(三)——在Intellij IDEA中配置Tomcat服务器
查看>>
Intellij IDEA使用(四)—— 使用Intellij IDEA创建静态的web(HTML)项目
查看>>
Intellij IDEA使用(五)—— Intellij IDEA在使用中的一些其他常用功能或常用配置收集
查看>>