java POI 读写 excel(项目实际需求)

本贴最后更新于 3911 天前,其中的信息可能已经时过境迁

这几天由于工作需要,需要做一个报表比对工具(找出两张报表的差异)。需求如下

1、做一个客户端工具,采用java,可以不用GUI(考虑到,我目前只懂j2ee相关的技术,其实这个需求用python(python版本)来做是最合适的,可是我目前不会,当然后面我会学习下这们语言)

2、两张报表的比队列需要灵活配置,通过配置文件来控制需要比对的列(可以是一列,可以是多列)

3、需要找出表A中有的一条数据,但是表B中没有的。或者表B中有的,表A中没有的。或者表A和表B同时都存在的一条数据,但是里面的某一些字段不一样。

4、两张报表的格式可能不一样,有可能为csv,xls,xlsx。两张报表的列数也是不固定的(这两张报表可以是任意的两张报表)

5、将比对结果再汇总到一张excel中(格式没有要求,我这里默认的是xls)

6、主键可能为复合主键,比对的报表,可能需要一次比对多组报表(由于这个需求,是今天才加上的,所以目前代码还处理这个问题,当然会很快加上)

思路一:

POI1-1

1、采用二维数组为主要的数据结构。因为,报表的列数不确定,所以不能构造对象,采用下标来控制每一列

2、将A表中的第一行的主键,然后搜索表B的主键,如果没搜到记下来,如果搜到了,比较所配置的列看是否相同,如果不同记下来,再反搜,表B中的主键来搜素表A,如果表B中有的,表A中没有的,记下来。

将记下来的数据重组,再导出excel。

效率:两张表都是30多列,52行,大概一秒左右比对完导出到excel中。

思路二

 POI1-2

1、主要采用了循环加map的方式,再比较是否有相等行的时候,直接用,表A的mapA.get(mapB.get("key"))如果数据不为空,说明在表A中有数据和表B匹配,这里的get有效的减少了一次循环。利用了map.get的方法速度更快。其他的。但是主要逻辑,还是如思路相同

接下来贴出,处理这个需求的主要代码。贴出代码的目的,主要是希望各位网友看到后,能够给指点一二,我这代码,肯定还需要优化,重构。或者说换思路。当然你有什么想法,通过评论,或者邮件告诉我。谢谢

ReadCSVExcel方法

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import au.com.bytecode.opencsv.CSVReader;

import com.qly.report.operate.facade.IReadExcel;

public class ReadCsvImpl implements IReadExcel{
static String qlyStringArr[][] = new String[1000][1000];
static String otherStringArr[][] = new String[1000][1000];
static Map<String,Integer > qlycontent = new HashMap<String,Integer >();
static Map<String,Integer > othercontent = new HashMap<String,Integer >();

@Override
public Map&lt;String, Object&gt; readExcel(String path, String flag) {
	CSVReader reader = null;
	// 取特定列放到集合
	try {
		InputStream ins = new FileInputStream(new File(path));
		InputStreamReader in = new InputStreamReader(ins, &quot;gbk&quot;);
		reader = new CSVReader(in);
		int len = reader.readNext().length;
		String nextline[];
		int counter = 0;
		// 将不同的来源的csv文件分别存放到不同的二维数组中
		if (&quot;qly&quot;.equals(flag)) {
			Map&lt;String, Object&gt; qlyMap = new HashMap&lt;String, Object&gt;();
			while ((nextline = reader.readNext()) != null) {
				for (int i = 0; i &lt; len; i++) {
					qlyStringArr[counter][i] = nextline[i];
				}
				counter++;
			}
			qlycontent.put(&quot;colNum&quot;, len);
			qlycontent.put(&quot;rowNum&quot;, counter);
			qlyMap.put(&quot;qlyStringArr&quot;, qlyStringArr);
			qlyMap.put(&quot;qlycontent&quot;, qlycontent);
			return qlyMap;
		}

		if (&quot;other&quot;.equals(flag)) {
			Map&lt;String, Object&gt; otherMap = new HashMap&lt;String, Object&gt;();
			while ((nextline = reader.readNext()) != null) {
				for (int i = 0; i &lt; len; i++) {
					otherStringArr[counter][i] = nextline[i];
				}
				counter++;
			}
			othercontent.put(&quot;colNum&quot;, len);
			othercontent.put(&quot;rowNum&quot;, counter);
			otherMap.put(&quot;othercontent&quot;, othercontent);
			otherMap.put(&quot;otherStringArr&quot;, otherStringArr);
			return otherMap;
		}

	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		try {
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	return null;
}

}

ReadXlsExcel 方法

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.qly.report.operate.facade.IReadExcel;
import com.qly.report.util.ReportUtil;

public class ReadXlsImpl implements IReadExcel{

public static HSSFWorkbook wb = null;
public static HSSFSheet hssfSheet =null;
public static HSSFRow hssfRow = null;
public static XSSFWorkbook xb = null;
public static XSSFSheet xssfSheet =null;
public static XSSFRow xssfRow =null;
public static String qlyStringArr[][] = new String[1000][1000];
public 	static String otherStringArr[][] = new String[1000][1000];
static Map&lt;String,Integer &gt; qlycontent = new HashMap&lt;String,Integer &gt;();
static Map&lt;String,Integer &gt; othercontent = new HashMap&lt;String,Integer &gt;();
@SuppressWarnings({ &quot;deprecation&quot; })
@Override
public Map&lt;String ,Object&gt; readExcel(String path, String flag) {
	int counter = 0;
	try {
		InputStream is = new FileInputStream(new File(path));

		wb = new HSSFWorkbook(is);
		hssfSheet = wb.getSheetAt(0);
		// 得到总行数
		int rowNum = hssfSheet.getLastRowNum();
		hssfRow = hssfSheet.getRow(1);

		int colNum = hssfRow.getPhysicalNumberOfCells();
		// 正文内容应该从第二行开始,第一行为表头内容
		if(&quot;qly&quot;.equals(flag)){
			Map&lt;String,Object&gt;qlyMap = new HashMap&lt;String, Object&gt;();
			for (int i = 1; i &lt; rowNum; i++) {
				hssfRow = hssfSheet.getRow(i);
				counter = 0;
				while (counter &lt; colNum) {
					qlyStringArr[i][counter] = get2003StringCellValue(
							hssfRow.getCell((short)counter)).trim();
					counter++;
				}
			}
			qlycontent.put(&quot;colNum&quot;, counter);
			qlycontent.put(&quot;rowNum&quot;, rowNum);
			qlyMap.put(&quot;qlyStringArr&quot;, qlyStringArr);
			qlyMap.put(&quot;qlycontent&quot;, qlycontent);
			return  qlyMap;
		}
		if(&quot;other&quot;.equals(flag)){
			Map&lt;String,Object&gt;otherMap = new HashMap&lt;String, Object&gt;();
			for (int i =1; i &lt; rowNum; i++) {
				hssfRow = hssfSheet.getRow(i);
				counter = 0;
				while (counter &lt; colNum) {
					otherStringArr[i][counter] = get2003StringCellValue(hssfRow.getCell((short) counter)).trim();
					
					counter++;
				}
			}
			othercontent.put(&quot;colNum&quot;, counter);
			othercontent.put(&quot;rowNum&quot;, rowNum);
			otherMap.put(&quot;othercontent&quot;, othercontent);
			otherMap.put(&quot;otherStringArr&quot;, otherStringArr);
			return otherMap;
		}


	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}	
	return null;
}
private static String get2003StringCellValue(HSSFCell cell) {
	String strCell = &quot;&quot;;
	
	if (null == cell) {
		return &quot;&quot;;
	}
	switch (cell.getCellType()) {
	case HSSFCell.CELL_TYPE_STRING:
		strCell = cell.getStringCellValue();
		break;
	case HSSFCell.CELL_TYPE_NUMERIC:
		//使用DecimalFormat类对科学计数法格式的数字进行格式化
		DecimalFormat df = new DecimalFormat(&quot;#&quot;);
		String str = String.valueOf(cell.getNumericCellValue());
		if(ReportUtil.isNumber(str)){
			strCell =  df.format(cell.getNumericCellValue());
		}else{
			strCell = str;
		}
		
		break;
	case HSSFCell.CELL_TYPE_BOOLEAN:
		
		strCell = String.valueOf(cell.getBooleanCellValue());
		break;
	case HSSFCell.CELL_TYPE_BLANK:
		strCell = &quot;&quot;;
		break;
	default:
		strCell = &quot;&quot;;
		break;
	}
	if (strCell.equals(&quot;&quot;) || null == strCell) {
		return &quot;&quot;;
	}
	return strCell;

}

}

ReadXlsxExcel方法

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.qly.report.operate.facade.IReadExcel;
import com.qly.report.util.ReportUtil;

public class ReadXlsxImpl implements IReadExcel {
public static HSSFWorkbook wb = null;
public static HSSFSheet hssfSheet =null;
public static HSSFRow hssfRow = null;
public static XSSFWorkbook xb = null;
public static XSSFSheet xssfSheet =null;
public static XSSFRow xssfRow =null;
public static String qlyStringArr[][] = new String[1000][1000];
public static String otherStringArr[][] = new String[1000][1000];
static Map<String,Integer > qlycontent = new HashMap<String,Integer >();
static Map<String,Integer > othercontent = new HashMap<String,Integer >();
@Override
public Map<String,Object> readExcel(String path, String flag) {
int counter = 0;
try {
InputStream is = new FileInputStream(new File(path));

		xb = new XSSFWorkbook(is);
		xssfSheet = xb.getSheetAt(0);
		// 得到总行数
		int rowNum = xssfSheet.getLastRowNum();
		xssfRow = xssfSheet.getRow(1);

		int colNum = xssfRow.getPhysicalNumberOfCells();
		// 正文内容应该从第二行开始,第一行为表头内容
		if(&quot;qly&quot;.equals(flag)){
			Map&lt;String,Object&gt;qlyMap = new HashMap&lt;String, Object&gt;();
			for (int i = 1; i &lt; rowNum; i++) {
				xssfRow = xssfSheet.getRow(i);
				counter = 0;
				while (counter &lt; colNum) {
					qlyStringArr[i][counter] = get2007StringCellValue(
							xssfRow.getCell((short) counter)).trim();
					counter++;
				}
			}
			qlycontent.put(&quot;colNum&quot;, counter);
			qlycontent.put(&quot;rowNum&quot;, rowNum);
			qlyMap.put(&quot;qlyStringArr&quot;, qlyStringArr);
			qlyMap.put(&quot;qlycontent&quot;, qlycontent);
			return  qlyMap;
		}
		if(&quot;other&quot;.equals(flag)){
			Map&lt;String,Object&gt;otherMap = new HashMap&lt;String, Object&gt;();
			for (int i = 1; i &lt; rowNum; i++) {
				xssfRow = xssfSheet.getRow(i);
				counter = 0;
				while (counter &lt; colNum) {
					otherStringArr[i][counter] = get2007StringCellValue(
							xssfRow.getCell((short) counter)).trim();
					counter++;
				}
			}
			othercontent.put(&quot;colNum&quot;, counter);
			othercontent.put(&quot;rowNum&quot;, rowNum);
			otherMap.put(&quot;othercontent&quot;, othercontent);
			otherMap.put(&quot;otherStringArr&quot;, otherStringArr);
			return otherMap;
		}
		
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	return null;
}
private static String get2007StringCellValue(XSSFCell cell) {
	String strCell = &quot;&quot;;
	if (null == cell) {
		return &quot;&quot;;
	}
	switch (cell.getCellType()) {
	case XSSFCell.CELL_TYPE_STRING:
		strCell = cell.getStringCellValue();
		break;
	case XSSFCell.CELL_TYPE_NUMERIC:
		//使用DecimalFormat类对科学计数法格式的数字进行格式化
		
		DecimalFormat df = new DecimalFormat(&quot;#&quot;);
		String str = String.valueOf(cell.getNumericCellValue());
		if(ReportUtil.isNumber(str)){
			strCell =  df.format(cell.getNumericCellValue());
		}else{
			strCell = str;
		}
		
		break;
	case XSSFCell.CELL_TYPE_BOOLEAN:
		strCell = String.valueOf(cell.getBooleanCellValue());
		break;
	case XSSFCell.CELL_TYPE_BLANK:
		strCell = &quot;&quot;;
		break;
	default:
		strCell = &quot;&quot;;
		break;
	}
	if (strCell.equals(&quot;&quot;) || null == strCell) {
		return &quot;&quot;;
	}
	return strCell;

}

}

 

 

CompareExcel方法,比较算法在这里

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.qly.report.operate.facade.ICompareExcel;
import com.qly.report.util.ReportUtil;
/**

  • by guop 2013-7-12 上午 9:11:06

  • 比较 excel
    */
    public class CompareExcelImpl implements ICompareExcel{

    @Override
    public Map<String ,Object> compareExcel(String [][] qlyString, String [][] otherString,
    int[] qlycolumn, int[] othercolumn,
    Map<String,Integer> qlycontent, Map<String,Integer> othercontent,
    int qlyflag, int otherflag, int qlystartRow, int otherstartRow,
    String outReportPath) {

     // 761报表的行数
     int qlyRowNum = qlycontent.get(&quot;rowNum&quot;);
     // 761报表的列数
     int otherRowNum = othercontent.get(&quot;rowNum&quot;);
    
     List&lt;Map&lt;String, Integer&gt;&gt; listErrorStr = new ArrayList&lt;Map&lt;String, Integer&gt;&gt;();
     // 在这里比较下,用a表的标记字段扫描b表从1开始,0为表头
     for (int i = qlystartRow; i &lt; qlyRowNum; i++) {
     	boolean boolflag = false;
     	boolean boolother = true;
     	Map&lt;String, Integer&gt; errorMap = new HashMap&lt;String, Integer&gt;();
    
     	for (int j = otherstartRow; j &lt; otherRowNum; j++) {
     		// 按照配置的标记列,如761中的票号,和腾邦的票号
     		// 表a中的第一行某字段,遍历表b中的行中的这一字段,看是否相同0
     		if (ReportUtil.handleSpecialCharacter(qlyString[i][qlyflag].trim()).equals(ReportUtil.handleSpecialCharacter(otherString[j][otherflag].trim()))) {
     			boolother = false;
     			int rowother = j;
     			// 在寻找到b表中,有相同的字段后,比较其他字段是否相同
     			for (int a1 = 0; a1 &lt; qlycolumn.length;a1++) {
     				if(null == qlyString[i][qlycolumn[a1]] || null == otherString[rowother][othercolumn[a1]]){
     					break;
     				}
    
     				// 当a表和b表中的 票面号相同,比较里面的规定的字段的值是否相同
     					if (!ReportUtil.handleSpecialCharacter(qlyString[i][qlycolumn[a1]].trim()).equals(ReportUtil.handleSpecialCharacter(otherString[rowother][othercolumn[a1]].trim()))) {
     						errorMap.put(&quot;qlylinenumber&quot;, i);
     						errorMap.put(&quot;otherlinenumber&quot;, rowother);
     						listErrorStr.add(errorMap);
     						boolflag = true;
     						break;
     					} 
     				}
    
     			if (boolflag) {
     				break;
     			}
     		}
     	}
     	if (boolother) {
     		errorMap.put(&quot;qlylinenumber&quot;, i);
     		listErrorStr.add(errorMap);
     	}
     }
     //用b表扫描a表的某一个字段
     		// 在这里比较下,用a表的标记字段扫描b表
     for (int i = otherstartRow; i &lt; otherRowNum; i++) {
     	boolean boolother = true;
     	Map&lt;String, Integer&gt; errorMap = new HashMap&lt;String, Integer&gt;();
     	for (int j = qlystartRow; j &lt; qlyRowNum; j++) {
    
     		// 按照配置的标记列,如761中的票号,和腾邦的票号
     		// 表a中的第一行某字段,遍历表b中的行中的这一字段,看是否相同0
     		if (ReportUtil.handleSpecialCharacter(qlyString[j][qlyflag].trim()).equals(ReportUtil.handleSpecialCharacter(otherString[i][otherflag].trim()))) {
     			boolother = false;
     			// 在寻找到b表中,有相同的字段后,比较其他字段是否相同
     		}
     	}
     	if (boolother) {
     		errorMap.put(&quot;otherlinenumber&quot;, i);
     		listErrorStr.add(errorMap);
     	}
     }
    
     Map&lt;String,Object&gt; compareMap = new HashMap&lt;String, Object&gt;();
     compareMap.put(&quot;listErrorStr&quot;, listErrorStr);
    

    return compareMap;
    }

}

全部代码在这里,github,请多多指教

  • POI
    22 引用 • 21 回帖
  • Excel
    30 引用 • 28 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone

    老船长这个不是专栏是博客吧。哈哈。专栏不是这个意思吧。

推荐标签 标签

  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    9 引用 • 32 回帖 • 164 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    164 引用 • 407 回帖 • 525 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    330 引用 • 614 回帖
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 383 回帖 • 4 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 5 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 22 关注
  • 周末

    星期六到星期天晚,实行五天工作制后,指每周的最后两天。再过几年可能就是三天了。

    14 引用 • 297 回帖 • 2 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    103 引用 • 294 回帖
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖 • 1 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 442 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    103 引用 • 126 回帖 • 446 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    122 引用 • 73 回帖
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 625 关注
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 590 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    16 引用 • 53 回帖 • 123 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 511 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    14 引用 • 7 回帖
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    180 引用 • 447 回帖
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    76 引用 • 37 回帖
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    75 引用 • 146 回帖
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    140 引用 • 441 回帖
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 3 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    172 引用 • 990 回帖
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    1 引用 • 11 回帖 • 2 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    129 引用 • 793 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    492 引用 • 1383 回帖 • 374 关注