精华内容
下载资源
问答
  • 在读代码的时候,并不会激活人类大脑涉及语言处理的区域。 相反,激活的是一个叫做多需求 (multiple demand,MD)网络的分布式网络。 而这个MD网络,通常在人们处理比较复杂的认知任务时被激活。 举个例子,数学...

    本文转载自 QbitAI

    都说学编程就像学一门新的语言,但事实真的如此吗?

    不不不,起码在读代码这件事上,你的大脑可不这么认为。

    在这里插入图片描述

    最近,MIT神经科学家在eLife期刊发表了一项新研究:

    在读代码的时候,并不会激活人类大脑涉及语言处理的区域

    相反,激活的是一个叫做多需求 (multiple demand,MD)网络的分布式网络。

    在这里插入图片描述

    而这个MD网络,通常在人们处理比较复杂的认知任务时被激活。

    举个例子,数学问题、填字游戏等……

    在这里插入图片描述

    怪不得……看别人的代码,一直有种很痛苦的赶脚,原来它真的是很“烧脑”啊!

    读代码时,你的大脑会发生什么?

    或许你会认为,代码嘛,本质上就是解决数学或逻辑相关的问题,那读代码会激活MD网络也是可以理解的。

    Too simple,too naive.

    MIT的研究人员进一步发现:

    尽管读代码的时候激活了MD网络,但和数学、逻辑问题相比,它似乎更加依赖这个网络的不同部分。

    也就是说,读代码时大脑的工作状态,还不能精确复制解数学问题时的大脑认知需求。

    通讯作者Anna A Ivanova这样表述道:

    理解计算机代码,不同于语言,也不同于数学和逻辑,仿佛是它自己的事情一样。

    嗯,有种“VIP专属区域”的味道了。

    研究人员测试的编程语言主要有2个:一个是Python;另一个是在少儿编程较火的可视化编程语言ScratchJr

    在这里插入图片描述

    测试对象是两组年轻人,分别对上述2个编程语言达到了精通状态。

    大致的测试过程是让这些年轻人平躺,工作人员会给他们展示代码片段文字描述 (如上图所示),并让他们预测这些代码将产生什么样的结果。

    在这个过程当中,研究人员还会用脑功能磁共振成像 (fMRI)来扫描,以此来检测这些年轻人大脑的活动。

    上述的实验是这次研究的“主实验”(上图A),除此之外,还有额外的2个“副实验”(上图B,与定位器相关):

    • MD System Localizer:困难模式,在出现的8个蓝色方块中,一次性记住2个的位置;简单模式,在出现的4个蓝色方块中,一次性记住1个的位置。
    • Language System Localizer:包括一个句子,以及非单词(一次出现一个)。

    对测试对象扫描过后,便得到了如下结果。

    在这里插入图片描述

    图中的A展示了MD网络在大脑左半球和右半球的位置,以及大脑涉及语言的区域。

    B和C分别展示了在读Python和ScratchJr代码或文本时,通过fMRI扫描得到的响应反馈情况。

    再具体的,SR代表句子阅读,NR代表非单词阅读,SP表示句子问题,CP表示代码问题。

    从实验结果难看出,大脑中的语言区域,几乎对代码问题(CP)没有反应,或者说反应极低。

    但十分意外的是,在读代码过程中,主要激活了MD网络,活动分布在大脑的额叶和顶叶。

    Anna A Ivanova对此表示道:

    MD网络几乎可以做任何具有认知挑战性的事情。

    然而,先前的研究表明,数学和逻辑问题似乎主要依赖于左脑的MD区域,而涉及空间导航的任务对右脑的激活程度要高于左脑。

    MIT这次的研究表明,读代码过程中,似乎同时激活了MD网络的左右两个部分;并且,读ScratchJr代码时,对右侧大脑的激活程度略高于左侧大脑。

    同时也推翻了以往的认知,即读代码时大脑的活动,和数学逻辑相同。

    到底更倾向于“数学逻辑”还是“语言”?

    对于人们在处理代码过程中,大脑的活动机制,更加倾向于“数学逻辑”还是“语言”,这个问题并不是第一次被拿出来研究。

    正如Anna A Ivanova所述,关于大脑如何学习编程,有两种思想派系:

    有人认为,为了擅长编程,人们必须强化数学能力。

    另一种观点是,由于编程和语言之间的相似性,语言技能可能更具相关性。

    第一次利用科学成像工具来做这方面研究的,需要追溯的2014年。

    来自帕绍大学(德国)、CMU等机构联手,对程序员大脑如何理解代码做了研究。

    在这里插入图片描述

    当时所采用的方法依旧是fMRI,参与测试的是17名精通Java的学生。

    被测试的学生,每个人都需要阅读不同的几段Java代码片段,且难度相似,因此研究人员可以平均得到的大脑成像数据。

    这项研究虽然并没有得到非常有力的结果,但第二作者表示:

    读代码更像“语言”,是错误的

    除了MIT这次在eLife发表的研究外,同期还有一篇配套论文,来自约翰·霍普金斯大学。

    在这里插入图片描述

    他们的研究也表明,读代码的过程中,大脑众多的MD网络被激活,而不是与语言相关的区域。

    至于在读代码时,大脑是否有专属的“工作区域”,MIT研究人员表示:

    虽然没有任何似乎明确的“编程区域”,但这种专属的大脑活动,可能在具备更多编程经验的人身上会有发展

    原文地址:https://mp.weixin.qq.com/s/AP1PIC2Vye3CgGJha4pTmQ

    展开全文
  • 阿里云复制镜像方法

    千次阅读 2019-10-06 11:48:49
    您可以复制某一地域中的自定义镜像到其他阿里云地域,并使用该镜像在相应地域创建ECS实例,即可在不同地域的ECS实例中运行同一镜像环境。本文介绍在同一账号下跨地域复制自定义镜像的操作步骤。 背景信息 镜像是一...

    复制镜像

    复制镜像适用于跨地域部署实例、跨地域备份数据。您可以复制某一地域中的自定义镜像到其他阿里云地域,并使用该镜像在相应地域创建ECS实例,即可在不同地域的ECS实例中运行同一镜像环境。本文介绍在同一账号下跨地域复制自定义镜像的操作步骤。

    背景信息

    镜像是一种地域性资源,自定义镜像归属于其被创建时的地域。不同场景的使用方式如下表所示。

     
    场景操作步骤描述
    跨地域同账号复制请参见复制镜像复制镜像时,会同时在目标地域生成对应的快照。复制完成后,在目标地域生成一个新镜像,新镜像具有唯一的镜像ID。
    跨地域跨账号复制请参见复制镜像共享镜像复制镜像到目标地域后,再共享镜像给目标账号。
    同地域跨账号共享请参见共享镜像共享镜像不会生成新的镜像,被共享的镜像仍归您所有。

    复制镜像前,请仔细阅读以下注意事项:

    • 复制镜像仅适用于自定义镜像。如果您需要复制其他类型的镜像,可先使用镜像创建实例,再使用该实例创建自定义镜像。然后,复制该自定义镜像。
    • 复制镜像时,会在目标地域生成对应的快照,随后在目标地域根据快照生成自定义镜像。因此,请注意可能产生的费用:
      • 不同地域间的数据传输流量费。目前未对这部分流量收费,具体收费时间以阿里云公告为准。
      • 复制的快照会占用快照容量。
    • 复制镜像后,您会在目标地域获得同样配置的一份自定义镜像。但是相关角色授权和服务授权信息会丢失,也不会包含原来设置过的实例自定义数据。
    • 复制镜像所需时间,取决于镜像文件大小、网络传输速度和并发任务的排队数量。
    • 暂不支持复制带加密快照的镜像。

    操作步骤

    1. 登录ECS管理控制台
    2. 在左侧导航栏,选择实例与镜像 > 镜像。
    3. 在顶部状态栏处,选择地域。
    4. 选择需要复制的镜像,镜像类型必须是自定义镜像,在操作列中,单击复制镜像。

      说明 如果您要复制的自定义镜像大于500 GiB,需要提交工单处理。当您单击复制镜像时,系统会引导您提交工单。

    5. 在复制镜像对话框中,您可以看到选中的自定义镜像的ID,您需要完成以下设置:
      1. 选择目标地域。
      2. 填写镜像在目标地域显示的自定义镜像名称和自定义镜像描述。
      3. 单击确定。
    6. 切换到目标地域,查看自定义镜像的复制进度。当进度显示为100%时,说明任务完成。

      说明 如果进度没到100%,状态为创建中时,您可以随时单击取消复制。取消任务后,目标地域的镜像列表中不再显示该自定义镜像。


    后续步骤

    • 当镜像的状态变为可用时,您可以使用复制的镜像创建实例或更换系统盘。具体操作,请参见创建实例更换系统盘(非公共镜像)
    • 您也可以在目标地域中查看从源地域复制过来的快照信息。

    相关文档

    展开全文
  • 缘起 最近写一个程序,需要操作...poi操作excel,复制sheet,复制行,复制单元格 使用POI操作Excel:Sheet拷贝 POI导出Excel时设置单元格类型为数值类型 问题 如果在copy一个cell的时候,需要把样式也copy过去,怎...

    缘起

    最近写一个程序,需要操作excel,遂稍微深入了解下poi从操作,

    在需要复制一个sheet的时候,找到三份资料

    问题

    如果在copy一个cell的时候,需要把样式也copy过去,怎么办,会怎样呢?

    如果像第三份资料中所做,会创建太多的style,而这些style又是重复的 ,毫无意义,数据多了还报错

    如果像第二份资料中所做,前提是同一个workbook,也不存在copy style 的问题,只不过是不同的cell引用相同的style而已

    如果像第一份资料所做,他自己都注释掉了,因为报错

    如何解决

    思路

    • 相同的book中,不需要copy
    • 不同的book中,styleTable应该不一致,copy的时候,在目标book中创建,最后返回两个book中的style index的映射关系

    代码

    暂时没测试过,写出来就迫不及待要分享了。

    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * 提供常用excel操作<br>
     *     <ul>
     *         <li></li>
     *     </ul>
     */
    public class ExcelOperationUtil {
        private static Logger logger = LoggerFactory.getLogger(ExcelOperationUtil.class);
        
        /**
         * 把一个excel中的styleTable复制到另一个excel中
         * @return StyleMapping 两个文件中styleTable的映射关系
         * @see StyleMapping
         */
        public static StyleMapping copyCellStyle(Workbook srcBook, Workbook desBook){
            if (null == srcBook || null == desBook) {
                throw new ExcelExecption("源excel 或 目标excel 不存在");
            }
            if (srcBook.equals(desBook)) {
                throw new ExcelExecption("不要使用此方法在同一个文件中copy style");
            }
    
            logger.debug("src中style number:{}, des中style number:{}", srcBook.getNumCellStyles(), desBook.getNumCellStyles());
            short[] src2des = new short[srcBook.getNumCellStyles()];
            short[] des2src = new short[desBook.getNumCellStyles() + srcBook.getNumCellStyles()];
    
            for(short i=0;i<srcBook.getNumCellStyles();i++){
                //建立双向映射
                CellStyle srcStyle = srcBook.getCellStyleAt(i);
                CellStyle desStyle = desBook.createCellStyle();
                src2des[srcStyle.getIndex()] = desStyle.getIndex();
                des2src[desStyle.getIndex()] = srcStyle.getIndex();
    
                //复制样式
                desStyle.cloneStyleFrom(srcStyle);
            }
    
            return new StyleMapping(des2src, src2des);
        }
    
        /**
         * 存放两个excel文件中的styleTable的映射关系,以便于在复制表格时,在目标文件中获取到对应的样式
         */
        public static class StyleMapping {
            /**
             *
             */
            private short[] des2srcIndexMapping;
            /**
             *
             */
            private short[] src2desIndexMapping;
    
            /**
             * 不允许其他类创建此类型对象
             */
            private StyleMapping() {
            }
    
            private StyleMapping(short[] des2srcIndexMapping, short[] src2desIndexMapping) {
                this.des2srcIndexMapping = des2srcIndexMapping;
                this.src2desIndexMapping = src2desIndexMapping;
            }
    
            public short srcIndex(short desIndex) {
                if (desIndex < 0 || desIndex >= this.des2srcIndexMapping.length) {
                    throw new ExcelExecption("索引越界:源文件styleNum=" + this.des2srcIndexMapping.length + " 访问位置=" + desIndex);
                }
                return this.des2srcIndexMapping[desIndex];
            }
    
            /**
             * 根据源文件的style的index,获取目标文件的style的index
             * @param srcIndex 源excel中style的index
             * @return desIndex 目标excel中style的index
             */
            public short desIndex(short srcIndex) {
                if (srcIndex < 0 || srcIndex >= this.src2desIndexMapping.length) {
                    throw new ExcelExecption("索引越界:源文件styleNum=" + this.src2desIndexMapping.length + " 访问位置=" + srcIndex);
                }
    
                return this.src2desIndexMapping[srcIndex];
            }
        }
    
    }

    完善代码

    工作忙了几天,终于可以回头把这件事结束掉了

            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>3.17</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.17</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-scratchpad</artifactId>
                <version>3.17</version>
            </dependency>

    为啥贴出依赖?因为我一开始用3.8版本,如果是xls就可以,如果是xlsx死活不行,最后,换掉版本就可以了。

    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.Iterator;
    
    /**
     * 提供常用excel操作<br>
     *     <ul>
     *         <li></li>
     *     </ul>
     */
    public class ExcelOperationUtil {
        private static Logger logger = LoggerFactory.getLogger(ExcelOperationUtil.class);
    
        /**
         * sheet 复制,复制数据、如果同一个文件,复制样式,不同文件则只复制数据<br/>
         * 如果是同book中复制,建议使用workbook中的cloneSheet()方法<br/>
         *
         * <br/>建议用于 不同book间只复制数据
         *
         */
        public static void copySheet(Sheet srcSheet, Sheet desSheet) {
            copySheet(srcSheet, desSheet, true, true, null);
        }
    
        /**
         * sheet 复制,如果同一个文件,复制样式,不同文件则不复制<br/>
         *
         * <br/>建议用于 同book中,只复制样式,不复制数据<br/>
         * eg: copySheet(srcSheet, desSheet, false)
         *
         * @param copyValueFlag 控制是否复制数据
         */
        public static void copySheet(Sheet srcSheet, Sheet desSheet, boolean copyValueFlag) {
            copySheet(srcSheet, desSheet, copyValueFlag, true, null);
        }
    
        /**
         * sheet 复制,复制数据、样式<br/>
         *
         * <br/>建议用于 不同book间复制,同时复制数据和样式<br/>
         * eg: copySheet(srcSheet, desSheet, mapping)
         *
         * @param mapping 不同文件间复制时,如果要复制样式,必传,否则不复制样式
         */
        public static void copySheet(Sheet srcSheet, Sheet desSheet, StyleMapping mapping) {
            copySheet(srcSheet, desSheet, true, true, mapping);
        }
    
        /**
         * sheet 复制,复制数据<br/>
         *
         *  <br/>建议用于 同book中,只复制数据,不复制样式<br/>
         *  eg: copySheet(srcSheet, desSheet, false, null)
         *
         * @param srcSheet
         * @param desSheet
         * @param copyStyleFlag
         * @param mapping
         */
        public static void copySheet(Sheet srcSheet, Sheet desSheet, boolean copyStyleFlag, StyleMapping mapping) {
            copySheet(srcSheet, desSheet, true, copyStyleFlag, mapping);
        }
    
        /**
         * sheet 复制, 灵活控制是否控制数据、样式<br/>
         *
         * <br/>不建议直接使用
         *
         * @param copyValueFlag 控制是否复制数据
         * @param copyStyleFlag 控制是否复制样式
         * @param mapping       不同book中复制样式时,必传
         */
        public static void copySheet(Sheet srcSheet, Sheet desSheet, boolean copyValueFlag, boolean copyStyleFlag, StyleMapping mapping) {
            if (srcSheet.getWorkbook() == desSheet.getWorkbook()) {
                logger.warn("统一workbook内复制sheet建议使用 workbook的cloneSheet方法");
            }
    
            //合并区域处理
            copyMergedRegion(srcSheet, desSheet);
    
            //行复制
            Iterator<Row> rowIterator = srcSheet.rowIterator();
    
            int areadlyColunm = 0;
            while (rowIterator.hasNext()) {
                Row srcRow = rowIterator.next();
                Row desRow = desSheet.createRow(srcRow.getRowNum());
                copyRow(srcRow, desRow, copyValueFlag, copyStyleFlag, mapping);
    
                //调整列宽(增量调整)
                if (srcRow.getPhysicalNumberOfCells() > areadlyColunm) {
                    for (int i = areadlyColunm; i < srcRow.getPhysicalNumberOfCells(); i++) {
                        desSheet.setColumnWidth(i, srcSheet.getColumnWidth(i));
                    }
                    areadlyColunm = srcRow.getPhysicalNumberOfCells();
                }
            }
        }
    
        /**
         * 复制行
         */
        public static void copyRow(Row srcRow, Row desRow) {
            copyRow(srcRow, desRow, true, true, null);
        }
    
        /**
         * 复制行
         */
        public static void copyRow(Row srcRow, Row desRow, boolean copyValueFlag) {
            copyRow(srcRow, desRow, copyValueFlag, true, null);
        }
    
        /**
         * 复制行
         */
        public static void copyRow(Row srcRow, Row desRow, StyleMapping mapping) {
            copyRow(srcRow, desRow, true, true, mapping);
        }
    
        /**
         * 复制行
         */
        public static void copyRow(Row srcRow, Row desRow, boolean copyStyleFlag, StyleMapping mapping) {
            copyRow(srcRow, desRow, true, copyStyleFlag, mapping);
        }
    
        /**
         * 复制行
         */
        public static void copyRow(Row srcRow, Row desRow,boolean copyValueFlag, boolean copyStyleFlag, StyleMapping mapping) {
            Iterator<Cell> it = srcRow.cellIterator();
            while (it.hasNext()) {
                Cell srcCell = it.next();
                Cell desCell = desRow.createCell(srcCell.getColumnIndex());
                copyCell(srcCell, desCell, copyValueFlag, copyStyleFlag, mapping);
            }
        }
    
        /**
         * 复制区域(合并单元格)
         */
        public static void copyMergedRegion(Sheet srcSheet, Sheet desSheet) {
            int sheetMergerCount = srcSheet.getNumMergedRegions();
            for (int i = 0; i < sheetMergerCount; i++) {
                desSheet.addMergedRegion(srcSheet.getMergedRegion(i));
                CellRangeAddress cellRangeAddress = srcSheet.getMergedRegion(i);
            }
        }
    
        /**
         * 复制单元格,复制数据,如果同文件,复制样式,不同文件则不复制样式
         */
        public static void copyCell(Cell srcCell, Cell desCell) {
            copyCell(srcCell, desCell, true, true,null);
        }
    
        /**
         * 复制单元格, 如果同文件,复制样式,不同文件则不复制样式
         * @param copyValueFlag 控制是否复制数据
         */
        public static void copyCell(Cell srcCell, Cell desCell, boolean copyValueFlag) {
            copyCell(srcCell, desCell, copyValueFlag, true, null);
        }
    
        /**
         * 复制单元格,复制数据,复制样式
         * @param mapping       不同文件间复制时,如果要复制样式,必传,否则不复制样式
         */
        public static void copyCell(Cell srcCell, Cell desCell,  StyleMapping mapping) {
            copyCell(srcCell, desCell, true, true, mapping);
        }
    
        /**
         * 复制单元格,复制数据
         * @param copyStyleFlag 控制是否复制样式
         * @param mapping       不同文件间复制时,如果要复制样式,必传,否则不复制样式
         */
        public static void copyCell(Cell srcCell, Cell desCell, boolean copyStyleFlag, StyleMapping mapping) {
            copyCell(srcCell, desCell, true, copyStyleFlag, mapping);
        }
    
        /**
         * 复制单元格
         * @param copyValueFlag 控制是否复制单元格的内容
         * @param copyStyleFlag 控制是否复制样式
         * @param mapping 不同文件间复制时,如果需要连带样式复制,必传,否则不复制样式
         */
        public static void copyCell(Cell srcCell, Cell desCell, boolean copyValueFlag, boolean copyStyleFlag, StyleMapping mapping) {
            Workbook srcBook = srcCell.getSheet().getWorkbook();
            Workbook desBook = desCell.getSheet().getWorkbook();
    
            //复制样式
            //如果是同一个excel文件内,连带样式一起复制
            if (srcBook == desBook && copyStyleFlag) {
                //同文件,复制引用
                desCell.setCellStyle(srcCell.getCellStyle());
            } else if (copyStyleFlag) {
               //不同文件,通过映射关系复制
                if (null != mapping) {
                    short desIndex = mapping.desIndex(srcCell.getCellStyle().getIndex());
                    desCell.setCellStyle(desBook.getCellStyleAt(desIndex));
                }
            }
    
            //复制评论
            if (srcCell.getCellComment() != null) {
                desCell.setCellComment(srcCell.getCellComment());
            }
    
            //复制内容
            desCell.setCellType(srcCell.getCellTypeEnum());
    
            if (copyValueFlag) {
                switch (srcCell.getCellTypeEnum()) {
                    case STRING:
                        desCell.setCellValue(srcCell.getStringCellValue());
                        break;
                    case NUMERIC:
                        desCell.setCellValue(srcCell.getNumericCellValue());
                        break;
                    case FORMULA:
                        desCell.setCellFormula(srcCell.getCellFormula());
                        break;
                    case BOOLEAN:
                        desCell.setCellValue(srcCell.getBooleanCellValue());
                        break;
                    case ERROR:
                        desCell.setCellValue(srcCell.getErrorCellValue());
                        break;
                    case BLANK:
                        //nothing to do
                        break;
                    default:
                        break;
                }
            }
    
        }
    
    
        /**
         * 把一个excel中的styleTable复制到另一个excel中<br>
         * 如果是同一个excel文件,就不用复制styleTable了
         * @return StyleMapping 两个文件中styleTable的映射关系
         * @see StyleMapping
         */
        public static StyleMapping copyCellStyle(Workbook srcBook, Workbook desBook){
            if (null == srcBook || null == desBook) {
                throw new ExcelException("源excel 或 目标excel 不存在");
            }
            if (srcBook.equals(desBook)) {
                throw new ExcelException("不要使用此方法在同一个文件中copy style,同一个excel中复制sheet不需要copy Style");
            }
            if ((srcBook instanceof HSSFWorkbook && desBook instanceof XSSFWorkbook) ||
                    (srcBook instanceof XSSFWorkbook && desBook instanceof HSSFWorkbook)) {
                throw new ExcelException("不支持在不同的版本的excel中复制样式)");
            }
    
            logger.debug("src中style number:{}, des中style number:{}", srcBook.getNumCellStyles(), desBook.getNumCellStyles());
            short[] src2des = new short[srcBook.getNumCellStyles()];
            short[] des2src = new short[desBook.getNumCellStyles() + srcBook.getNumCellStyles()];
    
            for(short i=0;i<srcBook.getNumCellStyles();i++){
                //建立双向映射
                CellStyle srcStyle = srcBook.getCellStyleAt(i);
                CellStyle desStyle = desBook.createCellStyle();
                src2des[srcStyle.getIndex()] = desStyle.getIndex();
                des2src[desStyle.getIndex()] = srcStyle.getIndex();
    
                //复制样式
                desStyle.cloneStyleFrom(srcStyle);
            }
    
    
            return new StyleMapping(des2src, src2des);
        }
    
        /**
         * 存放两个excel文件中的styleTable的映射关系,以便于在复制表格时,在目标文件中获取到对应的样式
         */
        public static class StyleMapping {
            /**
             *
             */
            private short[] des2srcIndexMapping;
            /**
             *
             */
            private short[] src2desIndexMapping;
    
            /**
             * 不允许其他类创建此类型对象
             */
            private StyleMapping() {
            }
    
            public StyleMapping(short[] des2srcIndexMapping, short[] src2desIndexMapping) {
                this.des2srcIndexMapping = des2srcIndexMapping;
                this.src2desIndexMapping = src2desIndexMapping;
            }
    
            public short srcIndex(short desIndex) {
                if (desIndex < 0 || desIndex >= this.des2srcIndexMapping.length) {
                    throw new ExcelException("索引越界:源文件styleNum=" + this.des2srcIndexMapping.length + " 访问位置=" + desIndex);
                }
                return this.des2srcIndexMapping[desIndex];
            }
    
            /**
             * 根据源文件的style的index,获取目标文件的style的index
             * @param srcIndex 源excel中style的index
             * @return desIndex 目标excel中style的index
             */
            public short desIndex(short srcIndex) {
                if (srcIndex < 0 || srcIndex >= this.src2desIndexMapping.length) {
                    throw new ExcelException("索引越界:源文件styleNum=" + this.src2desIndexMapping.length + " 访问位置=" + srcIndex);
                }
    
                return this.src2desIndexMapping[srcIndex];
            }
        }
    
    }
    

    一个自定义异常类

    
    public class ExcelException extends RuntimeException {
    
        public ExcelException() {
        }
    
        public ExcelException(String message) {
            super(message);
        }
    
        public ExcelException(String message, Throwable cause) {
            super(message, cause);
        }
    
        public ExcelException(Throwable cause) {
            super(cause);
        }
    
        public ExcelException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }
    }
    展开全文
  • 前些天与一位朋友技术交流,朋友在招人面试时想到一个问题,JVM垃圾回收时,会复制存活的对象到不同区域。比如从新生代复制到老年代,在此过程中,被复制的对象的地址是否变了呢?对他提出的这个问题很感兴趣,...

    前些天与一位朋友技术交流,朋友在招人面试时想到一个问题,JVM垃圾回收时,会复制存活的对象到不同的区域。比如从新生代复制到老年代,在此过程中,被复制的对象的地址是否变了呢?对他提出的这个问题很感兴趣,深入研究了一下,便有了这篇文章。

    更新引用是JVM的职责

    任何一款JVM的设计,采用任何一种GC算法进行对象的移动操作时,如何更新对象引用都是JVM的基本职责。也就是说,当移动对象时,必然会涉及到对象引用的变更,只不过这部分操作JVM已经帮我们做了。

    作为开发者来说,可以将引用理解为存储对象的抽象句柄,而不必担心JVM是如何管理对象存储的。但如果做技术研究,好奇底层的实现,倒是值得深入研究一下。

    当对象的实际地址发生变化时,简单来说,JVM会将指向该地址的一个或多个变量所使用的引用地址进行更新,从而达到在“不知不觉”中移动了对象的效果。

    JVM规范中只规定了引用类型是指向对象的引用,并没有限制具体的实现。因此,不同虚拟机的实现方式可能不同。通常有两种实现形式:句柄访问和直接指针访问。

    句柄访问

    先来看一张图,句柄访问的形式是堆空间维护一个句柄池,对象引用中保存的是对象的句柄位置。在堆中的句柄包含对象的实例数据和类型数据的真实地址。

    image

    这种形式的实现好处很明显,引用中保存的对象句柄地址相对稳定(不变),当GC操作移动对象时只用维护句柄池中存储的信息即可,特别是多个变量都引用同一个句柄池中的句柄时,可以减少更新变量存储的引用,同时确保变量的地址不变。缺点就是多了一次中转,访问效率会有影响。

    直接指针访问

    直接指针访问省去了中间的句柄池,对象引用中保持的直接是对象地址。
    image
    这种方式很明显节省了一次指针定位的开销,访问速度快。但是当GC发生对象移动时,变量中保持的引用地址也需要维护,如果多个变量指向一个地址,需要更新多次。Hot Spot虚拟机便是基于这种方式实现的。

    如何查看引用地址?

    上面聊了对象引用的实现形式,那么在日常开发中是否可以通过打印等形式来查看对象的地址吗?有这样一个说法,通过对象默认的toString方法打印出来的信息中包含对象的引用地址。下面我们通过一个实例来看看:

    Bike bike = new Bike();
    System.out.println(bike);
    

    当我们执行上述程序时,控制台会打印出如下信息:

    com.secbro2.others.Bike@4dc63996
    

    @后面的字符串是什么?是对象的地址吗?这种地址的说法其实在坊间流传了很久。我们先来看Object的toString源码:

    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
    

    通过源码我们会发现,其实@符合后面并不是对象的地址,而只是hashcode的十六进制展现形式而已。

    那么,如何打印对象的内存地址呢?我们需要依赖一个JOL(Java Object Layout)类库,在项目中添加如下Maven依赖:

    <dependency>
        <groupId>org.openjdk.jol</groupId>
        <artifactId>jol-core</artifactId>
        <version>0.10</version>
    </dependency>
    

    然后在程序中通过如下方法使用:

    String answer = "42";
    System.out.println("The memory address is " + VM.current().addressOf(answer));
    

    会发现打印的内容如下:

    The memory address is 31856221536
    

    上面的便是真实的内存地址,虽然能够获取并打印出内存地址,但由于不同环境下的JVM采用了不同的指针压缩操作。因此,我们不要基于此地址来做一些本机内存相关的操作。但上面的打印,明确的证明了toString方法打印出来的信息并不包括对象的内存地址。

    鉴于此,基于toString方法打印出来hashCode值只能保证两个对象的hashcode一样,却无法保证两个引用地址指向同一对象。

    小结

    通过与朋友的一个小交流,深挖一下,竟然发现不少底层的知识点,交流和探索的作用可见一斑。总结来说就是:JVM在GC操作时会自动维护引用地址,变量对应的应用地址是否变化要看采用的是基于句柄池方式还是直接指针指向的方式。同时,当我们通过toString方法打印时,输出的内容并不包含对象地址,只不过是对象hashcode的十六进制而已。


    程序新视界

    公众号“ 程序新视界”,一个让你软实力、硬技术同步提升的平台,提供海量资料

    微信公众号:程序新视界

    展开全文
  • 深入理解Java虚拟机-Java内存区域与内存溢出异常

    万次阅读 多人点赞 2020-01-03 21:42:24
    文章目录概述运行时数据区域程序计数器(线程私有)Java虚拟机栈(线程私有)局部变量表操作数栈动态链接方法返回地址小结本地方法栈(线程私有)Java堆(全局共享)方法区(全局共享)运行时常量池直接内存HotSpot...
  • 在活动目录集成主要区域的常规标签,你可以暂停和开始区域的运行,并且可以修改区域类型、复制方式和动态更新方式; 而在标准主要区域的常规标签,你可以暂停和开始区域的运行,并且可以修改
  • Java集合对象的深度复制与普通复制

    万次阅读 2015-10-30 21:27:21
    最近在开发中遇到了一些关于集合复制的一些问题,普通的集合复制只是将内存中栈的地址快拷贝一份,使得一个新的集合对象指向这个地址块,但是集合中的对象变量却是指向堆中的同一块区域。所以当拷贝的集合修改了集合...
  • JVM 内存区域

    万次阅读 2019-07-09 11:22:13
    一、JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区 域【JAVA 堆、方法区】、直接内存。 线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束 而 创建/销毁(在...
  • Java 虚拟机内存区域划分详解(1)

    千次阅读 2015-04-14 17:02:20
    我们一般在开发中认为JVM不过有堆和栈两部分组成,但是实际的Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着...
  • 今天来解决百度文库的复制问题,有些时候,比如做毛概,思修,伦理学的作业,就要经常复制百度文库的答案,但是百度要恰饭 ,所以无法直接复制(如图) 但是因为html的一些特性,或者是百度自己提供的功能,我们...
  • Eden 和 from 区域中存活的对象 ),则使用复制算法将这些仍然还存活的对象复制到另外一块 Survivor 区域 ( 即 to 区域 ) 中,然后清理所使用过的 Eden 以及 Survivor 区域 ( 即 from 区域 ),并且将这些对象的年龄...
  • C++编程语言中类对象的赋值与复制介绍(一)

    万次阅读 多人点赞 2018-08-20 17:17:07
    本系列文章主要介绍 C++ 编程语言中类对象的赋值操作、复制操作,以及两者之间的区别,另外还会介绍“深拷贝”与“浅拷贝”的相关知识。 本文为系列文章的第一篇,主要介绍 C++ 编程语言中类对象的赋值的相关知识。...
  • 陈永庭,饿了么框架工具部高级架构师,主要负责MySQL异地双向数据复制,支撑饿了么异地多活项目。曾就职于WebEx、Cisco、腾讯等公司。 今天我主要分享饿了么多活的底层数据实施,会和大家介绍在整个多活的设计和...
  • AXFR和IXFR区域传输及原理

    千次阅读 2017-09-15 10:54:36
    对于主要区域的其他服务器,必须进行区域传输,以便从主要区域复制和同步所有区域副本。 1. AXFR和IXFR区域传输 当新的DNS服务器添加到网络,并且配置为现有区域的新的辅助服务器时,它执行该区域的完全
  • DNS区域传输技术

    千次阅读 2018-12-18 10:22:08
    DNS区域传输技术 委托  例如,下图显示了 microsoft.com 域,该域包括 Microsoft 的域名。在单个服务器上首次创建 microsoft.com 域时,对于所有的 Microsoft DNS 名称空间,该域配置为单独区域。然而,如果这个 ...
  • Java内存区域怎么划分的?

    万次阅读 2020-09-18 15:12:57
    Java内存区域怎么划分的? 运行时数据区域包含以下五个区域:程序计数器,Java虚拟机栈,本地方法栈,堆,方法区(其中前三个区域各线程私有,相互独立,后面两个区域所有线程共享) 线程私用的部分(Java虚拟机栈,...
  • JVM的内存形式:   (1)方法区:存放了要加载的类的信息(名称,修饰符等)、类中的静态变量...方法区域也是全局共享的,在一定条件下它也会被GC,当方法区域要使用的内存超过其运行的大小时,会抛出OutOfMemo
  • 分布式系统副本复制和一致性

    千次阅读 2015-07-09 16:33:08
    复制可以提高系统的可靠性显而易见,多个副本可以用于分流(如数据库的一主多从结构)也可以用于加快响应时间(如cdn),这使得复制具有增强系统可用性和扩展性的效用。实现数据复制,不仅会涉及到副本的管理(包括...
  • ArcGIS数据库复制与同步更新

    千次阅读 2013-12-20 15:14:00
    说到ArcGIS数据库复制,就不得不先提下分布式数据库.所谓的分布式数据库,常是由一组物理上或逻辑上分布的计算机组成,各个子节点相对独立但又互相协同进行工作,共同组成一个完整的、全局的大型数据库。   ...
  • JVM内存区域详解

    千次阅读 2016-11-30 14:22:50
    JVM内存模型总体架构图 ...线程私有的内存区域。如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为空。 虚拟机栈 线程私有的,与线程在同一时间创建。管理J
  • 分布式一致性与复制-01

    千次阅读 2013-06-01 13:28:46
    1、数据复制的好处 分布式系统中数据的复制是为了提高系统的 可靠性、性能。 实现数据复制的难点:保持各个副本间的一致性。 首先:数据复制可以提高系统可靠性,一个副本失效后,可以转换到另一个副本继续运行;...
  • Redis详解(4)- 主从复制原理

    千次阅读 2019-06-03 11:10:05
    1、概述 Master节点在平时提供服务,另外一个或多个Slave节点在平时不提供服务(或只提供数据读取服务)。...Redis的主从复制功能除了支持一个Master节点对应多个Slave节点的同时进行复制外,还支持Slave节...
  • JVM运行时数据区域及GC

    千次阅读 2015-07-09 19:41:06
    JVM在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途、创建和销毁的时间。本文以Sun公司HotSpot虚拟机为例进行说明,JRockit和IBM J9会有所不同。HotSpot运行时数据...
  • JVM规范中的五大java内存区域

    万次阅读 多人点赞 2016-03-31 16:07:53
    JVM在执行java程序时会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间。有的数据区域随着JVM的进程而启动,有的数据区域则依赖于用户线程的启动和结束而创建和销毁
  • DNS学习笔记之5 - DNS区域详解

    千次阅读 2012-01-06 11:30:24
    DNS学习笔记之5 - DNS... DNS服务器类型: 根据管理的DNS区域不同,DNS服务器也具有不同的类型。一台DNS服务器可以同时管理多个 现在我们基本清楚了DNS服务器用于各种环境下的设置方式,建立是很简单的。我这
  • 浅析Android中的复制粘贴控制

    千次阅读 2017-08-11 20:16:00
    浅析Android中的复制粘贴控制我们都知道在Android系统的WebView中或者EditText上长按可以实现复制粘贴的功能,但是我们如果想要复制粘贴更多东西而不仅仅是文本,或者在粘贴时对粘贴的对象进行处理过滤一些不希望...
  • 加快系统文件复制速度必杀技

    千次阅读 2005-03-07 20:35:00
    本文将会你一个答案,同时你还可以看到如何加速复制速度等相关技巧。 复制的入门必修课 1.学习更快捷的复制方法 我们平时最常用的复制方法:右击文件或文件夹,或选中文件中要复制的文字后单击鼠标右键,在弹出的...
  • jQuery中DOM节点删除、复制、替换、

    千次阅读 2017-05-15 23:45:11
    要移除页面上节点是开发者常见的操作,jQuery提供了几种不同的方法用来处理这个问题,这里我们开仔细了解下empty方法 empty 顾名思义,清空方法,但是与删除又有点不一样,因为它只移除了 指定元素中的所有子节点...
  • 【java总结】jvm虚拟机内存区域

    万次阅读 2019-05-22 13:58:33
    java虚拟机堆栈区域 JVM区域总体分两类,heap区和非heap区。 heap区又分为: Eden Space(伊甸园)、 Survivor Space(幸存者区)、 Old Gen(老年代)。 非heap区又分: Code Cache(代码缓存区); Perm Gen...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 161,494
精华内容 64,597
关键字:

如何同时复制不同区域