六、ibatis1.2.8查询性能优化,实现百万数据zip导出
经测试发现将查询的结果100万数据(池子中共有大概14亿的数据)写入Excle文件并进行压缩导出zip文件最耗时的地方竟然在查询,因此本篇文章主要是针对如何在spring+ibatis1.2.8中优化查询
1)对查询的SQL进行优化,表数据量特别大(上亿、上十亿)的时候可以按照查询条件中的某个字段如:finish_time进行分区存储或者建立复合索引或者分区复合索引
2)有博友说在ibatis映射器<select>元素中增加fetchSize属性,可惜ibatis1.2.8不支持该属性。其在2.0版本中才增加了该属性(未确认是否属实)。让人豁然开朗的是
在Statement和ResultSet接口中都有提供有setFetchSize方法,因此优化的出发点就有了。使用spring的JdbcTemplate获取数据源信息后再使原始的jdbc方法进行查询优化
<select id="getPersonCount" resultClass="PoersonResult" parameterClass="PoersonBean" fetchSize="1000">
1、什么是fetchSize
对Oracle中的fetchsize的理解,当我们执行一个SQL查询语句的时候,需要在客户端和服务器端都打开一个游标,并且分别申请一块内存空间,作为存放查询的数据的一个缓冲区。这块内存区,存放多少条数据就由fetchsize来决定,同时每次网络包会传送fetchsize条记录到客户端。应该很容易理解,如果fetchsize设置为20,当我们从服务器端查询数据往客户端传送时,每次可以传送20条数据,但是两端分别需要20条数据的内存空闲来保存这些数据。fetchsize决定了每批次可以传输的记录条数,但同时,也决定了内存的大小。这块内存,在oracle服务器端是动态分配的(大家可以想想为什么)。而在客户端(JBOSS),PS对象会存在一个缓冲中(LRU链表),也就是说,这块内存是事先配好的,
应用端内存的分配在conn.prepareStatement(sql)或都conn.CreateStatement(sql)的时候完成。
setFetchSize 最主要是为了减少网络交互次数设计的。访问ResultSet时,如果它每次只从服务器上取一行数据,则会产生大量的开销。setFetchSize的意 思是当调用rs.next时,ResultSet会一次性从服务器上取得多少行数据回来,这样在下次rs.next时,它可以直接从内存中获取出数据而不 需要网络交互,提高了效率。 这个设置可能会被某些JDBC驱动忽略的,而且设置过大也会造成内存的上升。
参看博文:
https://blog.csdn.net/bincavin/article/details/8727612
https://blog.csdn.net/hx756262429/article/details/8196845
2、Statement接口和ResultSet接口中setFetchSize(int rows)理解
1)Statement接口中解释如下:
为JDBC 驱动程序提供一个提示,它提示此Statement 生成的ResultSet 对象需要更多行时应该从数据库获取的行数。指定的行数仅影响使
用此语句创建的结果集合。如果指定的值为 0,则忽略该提示。默认值为 0。
2)ResultSet接口中解释如下:
为 JDBC 驱动程序设置此ResultSet 对象需要更多行时应该从数据库获取的行数。如果指定的获取大小为零,则 JDBC 驱动程序忽略该值,
随意对获取大小作出它自己的最佳猜测。默认值由创建结果集的Statement 对象设置。获取大小可以在任何时间更改。
3、优化查询思路:使用spring的JdbcTemplate获取数据源后再使原始setFetchSize方法
原spring集成ibatis后使用getList()进行查询方法如下:
List org.biframework.dao.ibatis.BaseDao.getList(String statementName, Object parameterObject) throws DaoException
3.1)配置jdbcTemplate对象
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
3.2)获取JdbcTemplate对象
方法一:实现类(service)中利用构造器去获取JdbcTemplate对象
<bean id="stPolicyService"
class="org.bussiness.product.detailquery.service.StPolicyService">
<property name="stPolicyDao">
<ref local="stPolicyDao" />
</property>
<property name="jdbcTemplate">
<ref bean="jdbcTemplate" />
</property>
</bean>
同时在StPolicyService类中提供jdbcTemplate对象的set和get方法 方法二:Spring也我们提供了JdbcDaoSupport支持类,所有DAO继承这个类,就会自动获得JdbcTemplate(前提是注入DataSource)
<bean id="userDao" class="com.curd.spring.impl.UserDAOImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
spring集成ibatis进行项目中dao层基类封装可以参看我的博文:https://www.cnblogs.com/jiarui-zjb/p/9534810.html
3.3)点击导出按钮,生成Excle或者zip功能实现:
支持每个Excle文件最多15万条数据,每个sheet页最多5万条数据,导出数据量小于等于15万条则生成excle文件,大于15万条将生成zip文件
Action中的方法
if(count == 0){
response.setCharacterEncoding("GBK");
PrintWriter out = response.getWriter();
out.println("<script>");
out.println(" alert('您查询的数据数量为零!');");
out.println(" window.close();");
out.println("</script>");
return null;
}else if(count >= 1000000){
response.setCharacterEncoding("GBK");
PrintWriter out = response.getWriter();
out.println("<script>");
out.println(" alert('查询结果数据量偏大,请缩小查询范围!');");
out.println(" window.close();");
out.println("</script>");
return null;
}else{
List list = new ArrayList();
System.out.println("数据提取开始...");
if("1".endsWith(Kind)){
list = this.stPolicyService.getStPerm(nstPolicyBean);
}
String filename = "明细数据查询结果";
//response.setHeader("Connection", "close");
List head = new ArrayList();
head.add("机构ID");
head.add("机构名称");
head.add("渠道");
head.add("姓名");
head.add("年龄");
//工具类
ExcelTools excel = new ExcelTools();
long t1 = System.currentTimeMillis();
int exclNumber = excel.makeExcelNumber(list);
//1、将查询的结果集list中的数据拆分后放入ArrayList中
ArrayList spileList = excel.getSpileList(list,exclNumber);
long nowTime = System.nanoTime();
String tempExclePath=request.getRealPath("/") + File.separator +"WEB-INF"+File.separator+"temp"+File.separator+"excle"+File.separator+File.separator+nowTime;
//存放excle的文件夹
File excleFile=new File(tempExclePath);
//2.1生成exlce文件
if(spileList.size()==1){
excel.makeTempExcel(tempExclePath,filename,spileList,excel,head,excleFile);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(filename.getBytes("GBK"),"ISO8859-1") + ".xls\"");
FileInputStream excleInput =new FileInputStream(new File(tempExclePath+File.separator+filename+".xls"));
OutputStream os = response.getOutputStream();
int temp = 0;
byte[] buffer = new byte[1024 * 8];//缓冲区
while((temp = excleInput.read(buffer)) != -1){
os.write(buffer, 0,temp);
}
excleInput.close();
os.flush();
long end = System.currentTimeMillis();
System.out.println("共计耗时--"+(end-begin)/(1000)+"--秒");
//下载完之后清空zip目录下生成的临时文件
if(excel.deleteDir(new File(tempExclePath))){
System.out.println("删除临时生成的xls成功");
}
os.close();
}else {
//2.2生成zip文件
excel.makeTempExcel(tempExclePath,filename,spileList,excel,head,excleFile);
long makeExcleend = System.currentTimeMillis();
InputStream input = null;
//1)打包生成的zip文件目录
String tempZipPath=request.getRealPath("/") + File.separator+"WEB-INF"+File.separator+"temp"+File.separator+"zip"+File.separator+nowTime;
File tempZipFile=new File(tempZipPath);
if(!tempZipFile.exists()||!tempZipFile.isDirectory()){
tempZipFile.mkdirs();
} File zipFile = new File(tempZipPath+File.separator+filename+".zip");//要zip文件名
//2)zip输出流
//正确输出流
FileOutputStream zipFileFos = new FileOutputStream(zipFile);
ZipOutputStream zipOut = new ZipOutputStream(zipFileFos);
// 创建缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(zipOut,1024);
if(excleFile.isDirectory()){
File[] files = excleFile.listFiles();
for(int i = 0; i < files.length; ++i){
input = new FileInputStream(files[i]);
//3)逐一对需要打包的文件夹目录中的文件进行压缩,生成后的压缩文件目录名称为:短期险保单明细数据查询结果(存放files[i])
zipOut.putNextEntry(new ZipEntry(filename+ File.separator + files[i].getName()));
BufferedInputStream bis = new BufferedInputStream(input);
int temp = 0;
byte[] buffer = new byte[1024 * 8];//缓冲区
while((temp = bis.read(buffer)) != -1){
bos.write(buffer, 0,temp);
}
input.close();
}
zipOut.setEncoding("gbk"); }
zipOut.close();
zipFileFos.close();
//清空excle目录下生成的临时文件
if(excel.deleteDir(excleFile)){
System.out.println("删除临时生成的exlce成功");
}
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(filename.getBytes("GBK"),"ISO8859-1") + ".zip\"");
FileInputStream zipInput =new FileInputStream(zipFile);
OutputStream os = response.getOutputStream();
int temp = 0;
byte[] buffer = new byte[1024 * 8];//缓冲区
while((temp = zipInput.read(buffer)) != -1){
os.write(buffer, 0,temp);
}
long end = System.currentTimeMillis();
System.out.println("共计耗时--"+(end-begin)/(1000)+"--秒");
zipInput.close();
os.flush();
//下载完之后清空zip目录下生成的临时文件
if(excel.deleteDir(new File(tempZipPath))){
System.out.println("删除临时生成的zip成功");
}
os.close();
}
//excel.makeZipExcel(os, list, head, filename+".xls");
}
工具类中方法
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List; import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.NumberFormat;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException; import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream; public class ExcelTools { private int _SHEETSIZE = 50000;//每个sheet页多少条数据
private int xlsSheetNum = 3;//每个excle文件存在多少个sheet页 public int getXlsSheetNum() {
return xlsSheetNum;
} public void setXlsSheetNum(int xlsSheetNum) {
this.xlsSheetNum = xlsSheetNum;
} public int get_SHEETSIZE() {
return _SHEETSIZE;
} public void set_SHEETSIZE(int sheetsize) {
_SHEETSIZE = sheetsize;
} private static WritableFont wf = new WritableFont(WritableFont.ARIAL, 10,
WritableFont.BOLD, false);
private static WritableCellFormat wcfF = new WritableCellFormat(wf);
// 设置内容字体、字号等
private static WritableFont wft = new WritableFont(WritableFont.ARIAL, 10,
WritableFont.NO_BOLD, false);
private static WritableCellFormat wcfFt = new WritableCellFormat(wft);
// 设置合计字段字体、字号等
private static WritableCellFormat wcfFtotal = new WritableCellFormat(wf);
// 设置保费数值类型
private static NumberFormat nf = new NumberFormat("#,##0.00");
private static WritableCellFormat wcfN = new WritableCellFormat(nf);
// 设置其他费用数值类型
private static NumberFormat nft = new NumberFormat("#,##0");
private static WritableCellFormat wcfNt = new WritableCellFormat(nft); static {
try {
wcfF.setBorder(Border.ALL, BorderLineStyle.THIN);
wcfF.setAlignment(Alignment.CENTRE);
wcfFt.setBorder(Border.ALL, BorderLineStyle.THIN);
wcfFtotal.setAlignment(Alignment.CENTRE);
wcfFtotal.setBorder(Border.ALL, BorderLineStyle.THIN);
wcfN.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN);
wcfNt.setBorder(Border.ALL, BorderLineStyle.THIN);
} catch (WriteException e) {
e.printStackTrace();
}
} //服务器中不存在临时文件目录则进行创建
@SuppressWarnings("unchecked")
public void makeFile(File file, List datas, List head, boolean zip, String excelname)
throws FileNotFoundException, IOException, WriteException {
FileOutputStream out = new FileOutputStream(file);
if(zip){
makeZipExcel(out, datas, head,excelname);
}else{
makeExcel(out, datas, head);
}
out.flush();
out.close();
} //删除服务器WEB-INF/temp/excle/9725645661448目录及其下面的文件
@SuppressWarnings("unchecked")
public boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
//递归删除目录中的子目录下
for (int i=0; i<children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
System.out.println("删除失败");
return false;
}
}
}
// 目录此时为空,可以删除
return dir.delete();
} //生成多少个xls文件,每个xls文件为3个sheet页,每个sheet页_SHEETSIZE=50000条记录
public int makeExcelNumber(List datas)
throws IOException, WriteException {
int cycle =datas.size()%(_SHEETSIZE*xlsSheetNum)>=1?(datas.size()/(_SHEETSIZE*xlsSheetNum)+1):datas.size()/(_SHEETSIZE*xlsSheetNum);
return cycle;
} //仅仅生成xls文件
@SuppressWarnings("unchecked")
public void simpleMakeExcel(OutputStream out,List datas, List head,String xlsName)
throws IOException, WriteException {
WritableWorkbook wwb=Workbook.createWorkbook(out);
//创建多少个sheet页
int cycle = (datas.size() + (_SHEETSIZE - 1)) / _SHEETSIZE;
for (int i = 0; i < cycle; i++) {
makeSheet(wwb, datas, head, i);
}
wwb.write();
wwb.close();
}
//对所有数据按照每个exlce文件存放数量进行拆分放入list中
public ArrayList getSpileList(List list,int exclNumber){
ArrayList spileList=new ArrayList();
int baseRow;
if (exclNumber > 1) {
for (int i = 0; i < exclNumber; i++) {
//i=0为第一个sheet页没问题
ArrayList innerList = new ArrayList();
//index:第几个sheet页; _SHEETSIZE:每sheet页面数量大小10个
baseRow = (i+1)*xlsSheetNum*_SHEETSIZE;
//不足下一个xls文件时
for (int j=i*xlsSheetNum*_SHEETSIZE; j< baseRow; j++) {// 每个spileList元素存放多少条记录
if(j<list.size()){
innerList.add(list.get(j));
}
}
spileList.add(innerList);
}
} else {
spileList.add(0, list);
}
return spileList;
}
//生成.xls文件临时存放目录
public void makeTempExcel(String tempExclePath,String filename,ArrayList spileList,ExcelTools excel,List head,File excleFile){
if(!excleFile.exists()||!excleFile.isDirectory()){
excleFile.mkdirs();
}
for(int i=0;i<spileList.size();i++){
FileOutputStream fos=null;
try {
if(i==0){
fos = new FileOutputStream(new File(tempExclePath+File.separator+filename+".xls"));
}else {
fos = new FileOutputStream(new File(tempExclePath+File.separator+filename+i+".xls"));
}
try {
excel.simpleMakeExcel(fos,(List)spileList.get(i), head, "filename"+i+".xls");
} catch (WriteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
// 压缩
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} @SuppressWarnings("unchecked")
public void makeZipExcel(OutputStream out, List datas, List head,String xlsName)
throws IOException, WriteException {
ZipOutputStream zipout = new ZipOutputStream(out);
zipout.setEncoding("GBK");
ZipEntry entry = new ZipEntry(xlsName);
zipout.putNextEntry(entry); makeExcel(new BufferedOutputStream(zipout), datas, head); zipout.closeEntry();
zipout.flush();
zipout.close();
} @SuppressWarnings("unchecked")
public void makeExcel(OutputStream out, List datas, List head)
throws IOException, WriteException {
WritableWorkbook wwb = Workbook.createWorkbook(out);
int cycle = (datas.size() + (_SHEETSIZE - 1)) / _SHEETSIZE;
for (int i = 0; i < cycle; i++) {
makeSheet(wwb, datas, head, i);
}
wwb.write();
wwb.close();
} @SuppressWarnings("unchecked")
public void makeSheet(WritableWorkbook wwb, List datas, List head, int index)
throws WriteException {
int baseRow = index * _SHEETSIZE;
int endRow = (baseRow + _SHEETSIZE > datas.size()) ? datas.size() : (baseRow + _SHEETSIZE);
WritableSheet ws = wwb.createSheet((baseRow+1) + "-" + endRow, index); for (int i = 0; i < head.size(); i++) {
ws.addCell(new Label(i, 0, head.get(i).toString(), wcfF));
} for (int i = 0; i + baseRow < datas.size() && i < _SHEETSIZE; i++) {
Getable obj = (Getable) datas.get(i + baseRow);
for (int j = 0; j < head.size(); j++) {
Object o = obj.get(j);
if (o != null) {
if (o instanceof String) {
ws.addCell(new Label(j, i + 1, o.toString(), wcfFt));
} else if (o instanceof Double) {
ws.addCell(new Number(j, i + 1, ((Double) o)
.doubleValue(), wcfN));
} else if (o instanceof Integer) {
ws.addCell(new Number(j, i + 1, ((Integer) o)
.doubleValue(), wcfFt));
}
} else {
ws.addCell(new Label(j, i + 1, "", wcfFt));
}
}
} } }
service中的查询方法
public List getStPerm(StPolicyBean param) throws DaoException {
String sql = "SELECT T1.ORGAN_ID,T2.ORGNAME, FROM DM_COMM_USR T1 INNER JOIN DMUSER.D_ORG T2 ON (T1.ORGAN_ID = T2.ORGCODE)WHERE 1=1";
StringBuilder sb=new StringBuilder();
sb.append(sql);
if(param.getORGAN_ID()!=null&&!"".equals(param.getORGAN_ID())){
sb.append("AND T1.ORGAN_ID in (SELECT ORGAN_ID FROM ODSUSER.T_COMPANY_ORGAN START WITH ORGAN_ID = "+param.getORGAN_ID()+" "+"CONNECT BY PARENT_ID = PRIOR ORGAN_ID)");
}
if(param.getFINISH_TIME1()!=null&&!"".equals(param.getFINISH_TIME1())){
sb.append("AND T1.FINISH_TIME >= to_date("+"'"+param.getFINISH_TIME1().replace(" ", "")+"'"+",'yyyy-mm-dd')");
}
if(param.getFINISH_TIME2()!=null&&!"".equals(param.getFINISH_TIME2())){
sb.append("AND T1.FINISH_TIME <= to_date("+"'"+param.getFINISH_TIME2().replace(" ", "")+"'"+",'yyyy-mm-dd')");
}
sb.append("order by T1.ORGAN_ID"); System.out.println("sb.toString-->"+sb.toString());
DataSource dataSource = jdbcTemplate.getDataSource();
Connection conn = null;
PreparedStatement pst = null;
List<StPolicyBean> policyList = new ArrayList<StPolicyBean>();
ResultSet rs=null;
StPolicyBean stPolicyBean=null;
try {
conn = dataSource.getConnection();
conn.setAutoCommit(false);
pst = conn.prepareStatement(sb.toString());
pst.setFetchSize(5000);
rs = pst.executeQuery();
rs.setFetchSize(5000);
while (rs.next()) {
stPolicyBean = new StPolicyBean();
stPolicyBean.setORGAN_ID(rs.getString("ORGAN_ID"));
stPolicyBean.setORGNAME(rs.getString("ORGNAME"));
stPolicyBean.setDISTRCHNNNAME(rs.getString("DISTRCHNNNAME"));
policyList.add(stPolicyBean);
}
} catch (SQLException e) {
e.printStackTrace();
}
if (rs != null) { // 关闭记录集
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pst != null) { // 关闭声明
try {
pst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) { // 关闭连接对象
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return policyList;
}
上述代码复制粘贴后调试后即可运行,备注:上述将查询的代码放在service层了,最好是放到dao层进行实现。
参看博文:https://www.cnblogs.com/lichenwei/p/3902294.html
六、ibatis1.2.8查询性能优化,实现百万数据zip导出的更多相关文章
- 高性能mysql 第六章查询性能优化 总结(上)查询的执行过程
6 查询性能优化 6.1为什么查询会变慢 这里说明了的查询执行周期,从客户端到服务器端,服务器端解析,优化器生成执行计划,执行(可以细分,大体过程可以通过show profile查看),从服务器端返 ...
- SQL SERVER 查询性能优化——分析事务与锁(五)
SQL SERVER 查询性能优化——分析事务与锁(一) SQL SERVER 查询性能优化——分析事务与锁(二) SQL SERVER 查询性能优化——分析事务与锁(三) 上接SQL SERVER ...
- SQL Server查询性能优化——覆盖索引(二)
在SQL Server 查询性能优化——覆盖索引(一)中讲了覆盖索引的一些理论. 本文将具体讲一下使用不同索引对查询性能的影响. 下面通过实例,来查看不同的索引结构,如聚集索引.非聚集索引.组合索引等 ...
- Atitit 如何利用先有索引项进行查询性能优化
Atitit 如何利用先有索引项进行查询性能优化 1.1. 再分析的话就是我们所写的查询条件,其实大部分情况也无非以下几种:1 1.2. 范围查找 动态索引查找1 1.2.1. 索引联合 所谓的索引联 ...
- SQL Server 查询性能优化 相关文章
来自: SQL Server 查询性能优化——堆表.碎片与索引(一) SQL Server 查询性能优化——堆表.碎片与索引(二) SQL Server 查询性能优化——覆盖索引(一) SQL Ser ...
- mysql笔记03 查询性能优化
查询性能优化 1. 为什么查询速度会慢? 1). 如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减 ...
- Sql Server查询性能优化之走出索引的误区
据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是, ...
- SQL Server查询性能优化——堆表、碎片与索引(二)
本文是对 SQL Server查询性能优化——堆表.碎片与索引(一)的一些总结. 第一:先对 SQL Server查询性能优化——堆表.碎片与索引(一)中的例一的SET STATISTICS IO之 ...
- MySQL查询性能优化(精)
MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...
随机推荐
- 4_2 刽子手游戏(UVa489)<自顶向下逐步求精法>
Hangman Judge是一个猜英文单字的小游戏(在电子字典中常会看到),游戏规则如下:1.答案单字写在纸上(每个字元一张纸),并且被盖起来,玩家每次猜一个英文字元(letter).2.如果这个英文 ...
- 创业学习---《预判项目的长期壁垒》--B-3.预判模块---HHR计划---以太一堂
一,<开始学习> 1,投资人经常会问CEO:你的项目的长期壁垒是什么?你是怎么思考的? 2,三个预热思考题: (1)突然有一天,大公司要抄你,你会怎么办? 答:用增长技术来和他竞争. ( ...
- socket 多连接
socket 多连接 本文档为文档https://www.cnblogs.com/wodeboke-y/p/11241472.html 后续内容. 上一文档中的案例2给出了一个阻塞型socket se ...
- 23 JavaScript规范与最佳实践&性能&箭头函数
大多数web服务器(Apache等)对大小写敏感,因此命名注意大小写 不要声明字符串.数字和布尔值,始终把他们看做原始值而非对象,如果把这些声明为对象,会拖慢执行速度 对象是无法比较的,原始值可以 不 ...
- 对于java中反编译命令的使用以及Integer包装类的查看
Integer是基于int的包装类 我们可以用测试代码来看看Integer类是如何实现装箱和拆箱的 public class BoxAndUnbox { /** * @param args */ pu ...
- 生成唯一的ID
public class UniqueId { public static String getUUId(){ ; int hashCodeV = UUID.randomUUID().toString ...
- leetcode 0215
目录 ✅ 1002. 查找常用字符 描述 解答 java other's implementation(todo watch me) cpp py ✅ 821. 字符的最短距离 描述 解答 cpp p ...
- 【PAT甲级】1048 Find Coins (25 分)(二分)
题意: 输入两个正整数N和M(N<=10000,M<=1000),然后输入N个正整数(<=500),输出两个数字和恰好等于M的两个数(小的数字尽可能小且输出在前),如果没有输出&qu ...
- python中 with 的作用
with是 Python2.5 引入的一个新语法,它是一种上下文管理协议,目的在于从流程中吧 try...except 和 finally 关键字和资源释放相关代码统统去掉,简化 try...exce ...
- PAT A1131 Subway Map
dfs,选择最优路径并输出~ 这道题难度非常炸裂,要求完完整整自己推一遍,DFS才算过关!思路:一遍dfs,过程中要维护两个变量,minCnt 中途停靠最少的站.minTransfer需要换成的最少次 ...