`
粟谷_sugu
  • 浏览: 26157 次
社区版块
存档分类
最新评论

对自己写的代码的反思

阅读更多
代码review
写这篇文章的原因是昨天在工作期间完成业务要求的时候,根据组长的要求写了自己的代码,结果在之后组长review的时候,发现了很多不足的地方,所以写这篇博客进行记录。
话不多说,先上原始代码。
public class DocValuesWarmUpListener extends AbstractSolrEventListener{
    private static final Logger logger = LoggerFactory.getLogger(DocValuesWarmUpListener.class);
    private List<String> fields;
    public DocValuesWarmUpListener(SolrCore core) {
        super(core);
    }


    @Override
    public void init(NamedList args) {
        super.init(args);
        fields = new ArrayList<>();
        NamedList o;
        if(args != null) {
            o = (NamedList) args.get("fields");
            if(o!=null && o instanceof NamedList) {
                for (int i = 0; i < o.size(); i++) {
                    fields.add((String) o.getVal(i));
                }
            }
        }


    }

    @Override
    public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher currentSearcher) {
        long start = System.currentTimeMillis();
        ExecutorService executorService = Executors.newFixedThreadPool(fields.size());
        try {
            //排序所需要用到的字段,用一个线程池多线程预热
            for(int i=0;i<fields.size();i++) {
                executorService.execute(new WarmUpDocValueThread(fields.get(i),newSearcher));
            }
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }finally {
            logger.info("warming up consumes ["+(System.currentTimeMillis()-start)+"] Millis");
        }

    }

    class WarmUpDocValueThread implements Runnable{

        private String field;
        private SolrIndexSearcher newSearcher;
        public WarmUpDocValueThread(String field,SolrIndexSearcher newSearcher) {
            this.field = field;
            this.newSearcher = newSearcher;
        }

        @Override
        public void run() {
            try {
                DocValues.getSorted(this.newSearcher.getLeafReader(), this.field);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这里先大概解释一下这段代码的业务需求。
由于在业务方进行一个查询工作的时候,发现有一段查询语句的时间抖动非常大,最长耗时可能到6000ms,快的时候在400ms左右。所以组长分析是该查询语句涉及到排序,而solr周期性的softCommit之后,会需要对整个docValue进行重新merge,所以会造成周期性的抖动。所以需要在softComiit之后先进行对docValue的预热。
确定逻辑后,让我上手完成这个逻辑。整个代码逻辑也不复杂,就是写一个eventListener,在init()方法中初始化solrconfig.xml的配置,在newSearcher()方法中对docValue进行预热。
所以写了以上这一版本,在组长review的时候,发现了很多不足,现在记录一下,也是以后尽量避免。
1: 在多线程并发情况下,没有设置主线程的堵塞,及在多线程同时对docValue进行预热的情况下,主线程并不等待预热完成而直接继续执行。针对这个问题,在修改的第一版本中,在多线程开启后,加入thread.join(),完成主线程的等待,在组长的建议下修改成了countDownLatch。这里顺便写一下countDownLatch和join用法的区别。
    本质上countDownLatch和join都实现同一个目的,即多线程并发编程时,当各别线程需要等待特定的其他线程任务执行完成后再执行时,用到以上两个方法。具体使用方法这里先不赘述了,主要讲讲不同的使用场景。
    在使用join时,阻塞线程必须等待其他线程任务完全结束后才能继续执行,而使用countDownLatch时,可以任意指定其他线程的执行程度。
    举个例子,此时有A,B,C三个线程进行任务执行,假设三个线程任务均为执行100的计数且A线程必须等到B,C计数完成再执行,此时用join或者countDownLatch都能完成任务要求。但是如果任务改成,A线程必须等到B,C都计数到50时,再开始执行,此时join不能完成这个要求,但是用countDownLatch时可以实现,即先
CountDownLatch cdl = new CountDownLatch(2)
//A线程
cld.await()
//B线程完成50次计数时
cld.countDown()
//C线程完成50次计数时
cld.countDown()

以上代码即可实现要求,以上仅为伪代码,实际编程时注意要把cld.countDown()写在finally里面,避免有一线程崩溃而造成死锁。
    第二个不足在于对代码的可配置化程度上,第一版的代码将代码参数写的过于生硬,很难被以后的代码复用,经过组长提示,对AbstractSolrEventListener源码的阅读发现有一个init方法,可以实现对schema.xml文件的配置参数的读取,果断覆写这个方法,将所需要预热的field配置在xml文件中。
    本文主要记录一下这次的经验。
分享到:
评论
1 楼 ZJKAICO 2018-03-21  

相关推荐

    GPT-4写代码能力提升21%!MIT新方法让LLM学会反思

    用这种方法写代码的时薪是要比普通开发人员便宜的。 利用二元奖励机制实现反思 正如网友所言,Reflexion赋予GPT-4的反思能力和人类的思考过程差不多: 可以简单用两个字来概括:反馈。 在这个反馈过程中,又可以...

    如何更好的学习写代码

    ### 如何更好地学习写代码 #### 一、面对编译错误和挑战时的应对策略 在编程学习过程中,经常会遇到的一大挑战就是面对大量的编译错误。这种情况通常是因为对语法不够熟悉所导致的。这时,我们需要有足够的耐心和...

    代码的艺术

    他的职业生涯和贡献说明了软件工程师的价值不仅仅在于写代码,更在于将个人的热情、专业知识和对代码艺术的追求结合在一起。 总而言之,《代码的艺术》不仅是一篇技术文章,更是对软件工程师职业生活的深刻反思和...

    重构极限编程XP的实践与反思

    TDD强调先写测试用例再编写功能代码,有助于确保代码的正确性,但可能导致过度测试。 反思XP,作者认为虽然XP在某些方面具有显著优势,如快速响应变化和紧密的客户协作,但同时也存在一些值得讨论的问题。例如,...

    每天写出好代码的5个建议03

    4. **反思和总结**:定期回顾自己的代码,分析存在的问题和改进的空间,形成良好的编码习惯。 总之,《每天写出好代码的5个建议03》通过简短的文字传达了提升代码质量的核心理念,即保证代码逻辑的正确性、增强代码...

    怎样看待大学期间的代码练习

    当达到100000行代码时,程序员通常对自己的编程能力充满信心,能有效应对大部分工作场景,并超越身边大多数同行。 然而,编写1000000行代码并非仅仅意味着熟练度的提升,更是一个深度学习和持续优化的过程。在这个...

    代码阅读技巧-编程能力提高的最有效途径

    通过高效地阅读和分析他人的代码,我们可以学习到新的编程技巧,理解不同编程范式,以及如何写出更优雅、更高效的代码。 首先,代码阅读的起点是对编程语言的基础掌握。了解并熟悉所读代码的语言特性和语法结构是必...

    如何写出高质量的VB代码

    在编程世界中,Visual Basic(VB)是一种深受程序员喜爱的编程语言,尤其对于初学者而言,它的语法简洁、直观。然而,写出高质量的VB代码...通过实践和反思,你可以逐渐打破旧的习惯,形成编写高质量VB代码的新习惯。

    如何编写无法维护的代码

    ### 如何编写无法维护的代码:深入解析与反思 #### 总体概述 本文通过一种讽刺的方式探讨了如何编写难以维护的代码。虽然标题看似戏谑,但实际上文章旨在揭示那些不利于代码可读性和可维护性的做法。对于软件开发...

    读者写者问题课程设计

    5. **共享代码**:多个读者和写者线程需共享对存储区操作的函数。 **设计说明书内容:** 1. **设计说明**:包含设计目标、系统配置、所使用的编程语言和工具等。 2. **数据结构与模块**:详细说明程序中数据结构的...

    重构极限编程_XP的实践与反思(PDF).rar

    作者通过丰富的实践经验和深入的理论分析,为我们揭示了在软件开发过程中如何有效地运用重构和XP方法,以提高代码质量、提升团队效率,并对这一过程进行反思。 极限编程是一种敏捷开发方法,它强调快速反馈、客户...

    2011第20届国际C语言混乱代码大赛源代码

    分析这些代码可以深化我们对C语言底层机制的理解,同时也能启发我们在编程实践中如何避免写出难以维护的“混乱”代码。 例如,一个常见的混乱代码策略是使用复杂的递归或嵌套循环,这可能会导致阅读难度极大,但...

    PerCM个人代码管理软件

    需要注意的是,这种全本浏览的方式,也可能是整理的方式,也是我所需要的,就是能够对自己所掌握的知识进行一个系统的整理,这个目前不去实现。 如果简化成为这样一个状态,perCDM不但可以搜索代码,而且可以同时搜索...

    代码阅读方法与代码质量武大20190428.pdf

    代码阅读是软件开发中至关重要的一个环节,它涵盖了多个方面的知识和技能,旨在提升开发者对已有代码的理解和改进能力。本讲座"代码阅读方法与代码质量"主要关注如何有效地进行代码阅读,理解代码质量的重要性,并...

    优美代码力作

    其次,【提前设计】和【少写代码】是实现优美代码的关键步骤。在动手编码之前,充分的设计和规划可以帮助减少冗余代码,保持代码结构清晰。当发现代码偏离初衷时,应及时停下,反思并调整,避免代码失控。使用代码...

    10 Things You Can Do To Write Better Code 写好代码的十个秘诀

    以下就是写好代码的十个秘诀: 1. **鲁棒性(Solid and Robust)**:确保代码在面对异常、边界条件或不可预见的情况时仍能稳定运行。例如,避免在计算时出现除以零的情况,或者在处理数组时检查边界。 2. **简洁性...

    《剑指offer》案例代码

    8. **实践与反思**:亲自运行和调试这些代码,可以加深对知识的理解,同时也能锻炼我们的编程技能,学会从实践中学习。 总的来说,这个压缩包文件为我们提供了一个实践和学习《剑指Offer》书中案例的宝贵资源。通过...

    Java 入门 基础 代码

    6. **控制流**:if语句、switch语句用于条件判断,while、for循环用于重复执行代码,理解它们的结构和用法对编写逻辑代码至关重要。 7. **数组**:数组是存储相同类型数据的集合,理解如何创建、遍历和操作数组对于...

    精通JavaScript 书籍源代码

    8. **JavaScript设计模式**:了解常用的JavaScript设计模式,如单例、工厂、观察者等,这些模式能帮助你写出可维护和可扩展的代码。 9. **性能优化**:讨论如何通过代码优化、减少HTTP请求、缓存策略等手段提高...

Global site tag (gtag.js) - Google Analytics