Nand_ECC_校验和纠错_详解
|
ECC的全称是Error Checking and Correction,是一种用于Nand的差错检测和修正算法。如果操作时序和电路稳定性不存在问题的话,NAND Flash出错的时候一般不会造成整个Block或是Page不能读取或是全部出错,而是整个Page(例如512Bytes)中只有一个或几个bit出错。ECC能纠正1个比特错误和检测2个比特错误,而且计算速度很快,但对1比特以上的错误无法纠正,对2比特以上的错误不保证能检测。
校验码生成算法的C语言实现 已经知道,异或运算的作用是判断比特位为1的个数,跟比特位为0的个数没有关系。如果有偶数个1则异或的结果为0,如果有奇数个1则异或的结果为1。 图表 1 出错Bit列地址定位的判决树 注意:图中的CP指的是求异或之后的结果中的CP
|
原文地址 http://linux.chinaunix.net/bbs/viewthread.php?tid=1116253&extra=page%3D1
终于基本看懂了。。。。
下面解释一下,也许可以给和我曾经一样迷茫的人一点帮助:
对于这个,别人总结出来的规则:
RP0只计算行索引的Bit0为0的行,RP1只计算行索引的Bit0为1的行;
RP2只计算行索引的Bit1为0的行,RP3只计算行索引的Bit1为1的行;
RP4只计算行索引的Bit2为0的行,RP5只计算行索引的Bit2为1的行;
RP6只计算行索引的Bit3为0的行,RP7只计算行索引的Bit3为1的行;
RP8只计算行索引的Bit4为0的行,RP9只计算行索引的Bit4为1的行;
RP10只计算行索引的Bit5为0的行,RP11只计算行索引的Bit5为1的行;
RP12只计算行索引的Bit6为0的行,RP13只计算行索引的Bit6为1的行;
RP14只计算行索引的Bit7为0的行,RP15只计算行索引的Bit7为1的行;
在接下来的描述中,称为行与位的对应关系
另注:
1.上述规则中的RP意思是Row Parity,更多的叫法叫做LP(Line Parity)。为了解释更容易看懂,依旧采用RP的说法。
2.对于第几行,采用Line的说法,比如第1行,其实就是行号为0的Line0.
3.对于行的奇偶性,此处采用Line Parity的说法。
当Line5的Line Parity为1的时候,
首先最简单的理解,也是最直接的理解,那就是,要把所有RP0~RP14中,对应包含着此行的那些最后要计算的值找出来,
我们可以先手动地根据下图:
一点点,掰手指头,慢慢地写出来,那就是:
RP1,RP2,RP5,RP6,RP8,RP10,RP12,RP14
换句话说,如果Line5的Line Parity为1的时候,
我们应该要计算RP1,RP2,RP5,RP6,RP8,RP10,RP12,RP14。
关于这点,我想大家没有什么好疑问的吧,因为这就是按照其规则的最简单,最通俗的理解。
所以,不论你用什么复杂的算法,反正是要记录并且计算这些RP的值,以便和后面的值进行计算。
但是,程序在此处,并没有将这些RP找出来,而只是直接对行号进行XOR异或:
reg3 ^= (uint8_t) i;
表面上看,这和我们要找出来,并计算的那些RP,并没啥关系,这也是我开始很困惑的问题。
按理来说,应该是找出那些行号,然后计算对应的RP的值,并保存,这样才对。
而此处之所以可以这么处理,主要是有以下原因:
1. 行与位的有如下对应关系:
RP0只计算行索引的Bit0为0的行,RP1只计算行索引的Bit0为1的行;
RP2只计算行索引的Bit1为0的行,RP3只计算行索引的Bit1为1的行;
RP4只计算行索引的Bit2为0的行,RP5只计算行索引的Bit2为1的行;
RP6只计算行索引的Bit3为0的行,RP7只计算行索引的Bit3为1的行;
RP8只计算行索引的Bit4为0的行,RP9只计算行索引的Bit4为1的行;
RP10只计算行索引的Bit5为0的行,RP11只计算行索引的Bit5为1的行;
RP12只计算行索引的Bit6为0的行,RP13只计算行索引的Bit6为1的行;
RP14只计算行索引的Bit7为0的行,RP15只计算行索引的Bit7为1的行;
2. 某一行号的二进制分解的对应bit,对应了所要计算的RP:
比如是第6行,也就是Line5,5的二进制是:
|
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
|
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
5的二进制值
而根据上面别人分析出来的,行与位的对应关系,我们可以找出,此二进制的每一位所对应了哪些RP:
bit为1的位,分别是0,2,对应代表的是RP1,RP5
bit为0的位,分别是1,3,4,5,6,7,对应代表的是RP2,RP6,RP8,RP10,RP12,RP14
用表格表示为:
|
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
|
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
|
RP14 |
RP12 |
RP10 |
RP8 |
RP6 |
RP5 |
RP2 |
RP1 |
5的二进制值和二进制对应的行
上表中,比如bit2是1,而别人说了“RP5只计算行索引的Bit2为1的行”,
所以,此处如果bit2为1,对应着RP5将要被计算,
那么我们可以肯定地得出来的是,
如果此行,Line5,的Line Parity是1的话,RP5是要被计算的。
而仔细观察就会发现,RP5,就包含在我们上面自己手动找出来的那些LP中:
RP1,RP2,RP5,RP6,RP8,RP10,RP12,RP14
而,剩下的bit位,也依次对应着这些LP。比如bit0为1,对应RP1.
这就是我们上面说的“某一行号的二进制分解的对应bit,对应了所要计算的RP”
也是理解如此处理的关键点之一。
同样地,除了bit为1的bit0,bit2,对应的RP1,RP5之外,
剩下的几个bit对应的RP2,RP6,RP8,RP10,RP12,RP14,由于对应位是0,所以,即使拿过来抑或,也还是0,无法记住这些bit的值,所以,采用将其取反,这样,对应这些为0的bit,就变成1了,就可以记住这些对应的bit了:
reg2 ^= ~((uint8_t) i);
这样,当从0到255检测的过程中,如果发现某行的Line Parity是1,
那么就将其行号数值进行抑或,以存储奇数的LP,将行号取反,以保存偶数的LP,
也就是:
Reg3对应的就是RP1,RP3,RP5,。。。,RP15
Reg2对应的就是RP0,RP2,RP4,。。。,RP14
然后再调用函数nand_trans_result(reg2, reg3, ecc_code);去将reg3和reg2中存储的信息,
重新组织到ecc[1]和ecc[2]中去。
最后的感慨是:
此处仅仅是通过对行号的数值抑或,以保存所要求的各个RP的值,之所以让人很难理解:
一是由于我们之前不知道上面的那个规则:“行与位的对应关系”
二是我们不知道,行号按位分解后,对应的bit位对应着所要计算的那些RP,“某一行号的二进制分解的对应bit,对应了所要计算的RP”
最后感谢各位作者和分享其分析过程的朋友。
代码:
Testecc.c
/*
* =====================================================================================
*
* Filename: TestEcc.c
*
* Description:
*
* Version: 1.0
* Created: 2009年06月04日 20时15分54秒
* Revision: none
* Compiler: gcc
*
* Author: Li Hongwang (mn), hoakee@gmail.com
* Company: University of Science and Technology of China
*
* =====================================================================================
*/
#include <stdio.h>
typedef unsigned char u_char;
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
/*
* Pre-calculated 256-way 1 byte column parity
*/
static const u_char nand_ecc_precalc_table[] = {
0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00,
0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65,
0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66,
0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03,
0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69,
0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C,
0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F,
0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A,
0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A,
0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F,
0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C,
0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69,
0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03,
0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66,
0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65,
0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00
};
/**
* * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block
* * @mtd: MTD block structure
* * @dat: raw data
* * @ecc_code: buffer for ECC
* */
int nand_calculate_ecc(const u_char *dat, u_char *ecc_code)
{
uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
int i;
/* Initialize variables */
reg1 = reg2 = reg3 = ;
/* Build up column parity */
for(i = ; i < ; i++) {
/* Get CP0 - CP5 from table */
idx = nand_ecc_precalc_table[*dat++];
reg1 ^= (idx & 0x3f);
/* All bit XOR = 1 ? */
if (idx & 0x40) {
reg3 ^= (uint8_t) i;
reg2 ^= ~((uint8_t) i);
}
}
/* Create non-inverted ECC code from line parity */
tmp1 = (reg3 & 0x80) >> ; /* B7 -> B7 */
tmp1 |= (reg2 & 0x80) >> ; /* B7 -> B6 */
tmp1 |= (reg3 & 0x40) >> ; /* B6 -> B5 */
tmp1 |= (reg2 & 0x40) >> ; /* B6 -> B4 */
tmp1 |= (reg3 & 0x20) >> ; /* B5 -> B3 */
tmp1 |= (reg2 & 0x20) >> ; /* B5 -> B2 */
tmp1 |= (reg3 & 0x10) >> ; /* B4 -> B1 */
tmp1 |= (reg2 & 0x10) >> ; /* B4 -> B0 */
tmp2 = (reg3 & 0x08) << ; /* B3 -> B7 */
tmp2 |= (reg2 & 0x08) << ; /* B3 -> B6 */
tmp2 |= (reg3 & 0x04) << ; /* B2 -> B5 */
tmp2 |= (reg2 & 0x04) << ; /* B2 -> B4 */
tmp2 |= (reg3 & 0x02) << ; /* B1 -> B3 */
tmp2 |= (reg2 & 0x02) << ; /* B1 -> B2 */
tmp2 |= (reg3 & 0x01) << ; /* B0 -> B1 */
tmp2 |= (reg2 & 0x01) << ; /* B7 -> B0 */
/* Calculate final ECC code */
#ifdef CONFIG_MTD_NAND_ECC_SMC
//ecc_code[0] = ~tmp2;
//ecc_code[1] = ~tmp1;
#else
//ecc_code[0] = ~tmp1;
//ecc_code[1] = ~tmp2;
#endif
ecc_code[] = tmp2;
ecc_code[] = tmp1;
//ecc_code[2] = ((~reg1) << 2) | 0x03;
ecc_code[] = ((reg1) << ) | 0x03;
return ;
}
static inline int countbits(uint32_t byte)
{
int res = ;
for (;byte; byte >>= )
res += byte & 0x01;
return res;
}
int nand_correct_data( u_char *read_ecc, u_char *calc_ecc)
{
uint8_t s0, s1, s2;
s0 = calc_ecc[] ^ read_ecc[];
s1 = calc_ecc[] ^ read_ecc[];
s2 = calc_ecc[] ^ read_ecc[];
if ((s0 | s1 | s2) == )
return ;
/* Check for a single bit error */
if( ((s0 ^ (s0 >> )) & 0x55) == 0x55 &&
((s1 ^ (s1 >> )) & 0x55) == 0x55 &&
((s2 ^ (s2 >> )) & 0x54) == 0x54) {
uint32_t byteoffs, bitnum;
byteoffs = (s1 << ) & 0x80;
byteoffs |= (s1 << ) & 0x40;
byteoffs |= (s1 << ) & 0x20;
byteoffs |= (s1 << ) & 0x10;
byteoffs |= (s0 >> ) & 0x08;
byteoffs |= (s0 >> ) & 0x04;
byteoffs |= (s0 >> ) & 0x02;
byteoffs |= (s0 >> ) & 0x01;
bitnum = (s2 >> ) & 0x04;
bitnum |= (s2 >> ) & 0x02;
bitnum |= (s2 >> ) & 0x01;
printf("Error Bit at: Byte %d, Bit %d.\n", byteoffs, bitnum);
return ;
}
if(countbits(s0 | ((uint32_t)s1 << ) | ((uint32_t)s2 <<)) == )
return ;
return -;
}
//
static const u_char raw_data[] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
};
// changed data. 0x34==>0x74
static const u_char new_data[] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x74,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
};
static uint8_t ecc_code_raw[];
static uint8_t ecc_code_new[];
int main()
{
int i=;
nand_calculate_ecc( raw_data, ecc_code_raw );
nand_calculate_ecc( new_data, ecc_code_new );
printf("\nRaw ECC Code: ");
for( i=; i< ; i++)
{
printf("0x%02X ", ecc_code_raw[i] );
}
printf("\nNew ECC Code: ");
for( i=; i< ; i++)
{
printf("0x%02X ", ecc_code_new[i] );
}
printf("\n");
nand_correct_data( ecc_code_raw, ecc_code_new );
printf("\n");
}
Nand_ECC_校验和纠错_详解的更多相关文章
- shell-的特殊变量-进程状态变量$$ $! $? $_详解
一:shell的特殊变量-进程状态变量详解 1. 进程状态变量 $$ 获取当前shell的进程号(pid) $! 执行上一个指令的pid,上一个后台运行进程的进程号 $? 获取执行上一个指令的返回值 ...
- 【NOIP2015普及组】推销员_详解
题目 题目大意 阿明是一名推销员--螺丝街是一条直线,一端有入口,一共有 \(N(<100,000)\) 家住户,第 \(i\) 家住户到入口的距离为 \(S_i\) 米.由于同一栋房子里可以有 ...
- Spring注解_详解
@Autowired 注释 将 @Autowired 注释标注在成员变量上 import org.springframework.beans.factory.annotation.Autowire ...
- TCP头校验和计算算法详解
我就不管是按“位”(bit)取反相加,还是 按“1的补码”相加了,总之就是把需要进行校验的“字串”加(+)起来,把这相加的 结果取反当做“校验和” (Checksum), 比如,相加的结果是0101, ...
- 终极优化_详解Win7旗舰版系统中可以关闭的服务
Win7旗舰版系统是一款功能强大的系统,不过对于很多用户很多功能却使用不上,而支持功能的很多服务也多少占用了系统资源,那么我们可以通过关闭一些不使用的服务来达到让win7系统运行速度加快的目的.下面小 ...
- phpcms v9联动菜单的调用方法_详解get_linkage函数
phpcms v9联动菜单调用方法[此为内容页调用方法]: {get_linkage($areaid,1,' >> ',1)} 显示效果: phpcms吧 >> 模板下载 &g ...
- confirm("确定要删除吗?") _详解
具体代码如下: html代码: <div class="deletes">删除</div> js代码: <script type="text ...
- Python说文解字_详解元类
1.深入理解一切接对象: 1.1 什么是类和对象? 首先明白元类之前要明白什么叫做类.类是面向对象object oriented programming的重要概念.在面向对象中类和对象是最基本的两个概 ...
- Android:TextView跑马灯-详解
Android:TextView跑马灯_详解 引言: TextView之所以需要跑马灯,是由于文字太长,或者是吸引眼球. 关键代码如下: android:singleLine="true&q ...
随机推荐
- mysql基本操作(二)
1.向表msg中插入数据,先创建表,再插入数据 mysql> create table msg ( -> id int, -> title varchar(60), -> na ...
- x86 版的 Arduino Intel Galileo 开发板的体验、分析和应用
1.前言 在今年(2013)罗马举办的首届欧洲 Make Faire 上,Intel 向对外发布了采用 x86 构架的 Arduino 开发板:Intel Galileo.这无疑是一个开源硬件领域的重 ...
- HTML—xhtml和html5
一.什么是XHTML? XHTML指的是可扩展超文本标记语言: XHTML与HTML 4.01几乎是相同的: XHTML是更严格跟纯净的HTML版本: XHTML是以XML应用的方式定义的HTML: ...
- POJ 1979 红与黑
题目地址: http://poj.org/problem?id=1979 或者 https://vjudge.net/problem/OpenJ_Bailian-2816 Red and Blac ...
- LRU缓存,大神写的,值得借鉴
http://blog.csdn.net/beiyeqingteng/article/details/7010411
- 第K人||约瑟夫环(链表)
http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4442 很容易超时 通过数组来记录,删除 //数组从1开始好像不行 后面一些数字就乱码了,因 ...
- eclipse配置tomcat,让java web项目运行起来!
做项目,搞开发.开发环境配置时第一步.只有环境搭好了,以后的事情才能顺利进行! 这不需求来了,负一屏项目有新功能需要添加,临时接手,要进行服务器前端开发.这个项目是以前后台java人员进行开发的.都是 ...
- MySQL数据库基本用法-聚合-分组
聚合 为了快速得到统计数据,提供了5个聚合函数 count(*)表示计算总行数,括号中写星与列名,结果是相同的 查询学生总数 select count(*) from students; max(列) ...
- linux 学习笔记 ftp
server with sites set up for download files sometimes provide an anonymous ftp account 数据传输 ftp 192. ...
- 大数据环境完全分布式搭建hbase-0.96.2-hadoop2
1.上传hbase安装包 2.解压 3.配置hbase集群,要修改3个文件 (首先zookeeper集群已经安装好了 并且启动 hadoop启动) 注意:要把hadoop的hdfs-site.xml和 ...


