每一个疑问背后都隐藏着至少一个盲点和学习的绝佳机会

简介: 每一个疑问背后都隐藏着至少一个盲点和学习的绝佳机会

一、背景

之前我好多次谈到:“每一个疑问背后至少有一个知识盲区,隐藏着一次极佳的学习机会”。

今天结合一个具体的案例,谈谈这个观念,顺便谈谈如何正确提问

今天有一个朋友问到:

请教一个问题 为什么用lombox的build构建一个对象内部持有的另外一个对象 用io的方式进行深克隆 拿到的两个内部对象是一样的 但是如果用set的方式给内部持有对象赋值 深克隆出来的就不是同一个对象

二、解答过程

2.1 存在的问题

首先这段描述不太清楚,没有标点。描述的问题显然和深拷贝的概念不符,但是描述的内容无法让解答的人有足够的线索能够为他解答问题。

2.2 引导

因此给出下面的回复:

1 先确认自己理解了 浅拷贝和深拷贝的概念

(之前一直强调的,是什么,为什么比怎么做更重要)

2 建议你写一个简单的模拟的例子再发出来方便讨论,因为部分描述不太容易理解甚至有歧义

比如

“用io的方式进行深克隆 拿到的两个内部对象是一样的” 一样的是指同一个对象?啥样的IO方式?怎么实现深克隆的?

“set的方式给内部持有对象赋值” 是set内部对象,还是set内部对象的属性

给出的进一步建议:

建议可以用commons-lang3 的 SerializationUtils.serialize 序列化为字节数组 SerializationUtils.deserialize反序列化为对象。(怕他序列化姿势有问题)

写个DEMO表达的更清楚一些(方便进一步分析问题)

然后该同学发来了代码:

附件类:

import java.io.Serializable;
@Data
@AllArgsConstructor
public class Attchment implements Serializable {
    private String name;
}

image.gif

待测试类:

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WeeklyLogByIO implements Serializable {
    private String name;
    private String date;
    private String content;
    private Attchment attchment;
    public WeeklyLogByIO deepClone() throws Exception{
        //将对象写入到流中
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        //将对象从流中取出
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (WeeklyLogByIO)ois.readObject();
    }
}

image.gif

测试代码:

public class SDemo {
    public static void main(String[] args) {
         WeeklyLogByIO logProvious = new WeeklyLogByIO();
        Attchment attchment = new Attchment("附件1");
        logProvious.builder().attchment(attchment).build();
        //logProvious.setAttchment(attchment);
        //开始克隆
        WeeklyLogByIO weekNew = null;
        try {
            weekNew = logProvious.deepClone();
        } catch (Exception e) {
            e.printStackTrace();
        }
        weekNew.setDate("第二周");
        System.out.println(logProvious == weekNew);
        System.out.println(logProvious.getAttchment() == weekNew.getAttchment());
    }
}

image.gif

输出的结果分别为 false 和 true。

和对方确认他的表达:

你表达的就是 为啥深拷贝,结果一个是 true 一个是 false 对吧,就是第二个打印语句输出的结果不对对吧?

这才清楚明白地搞清楚他真正想表达的意思。

看了DEMO 得出了两个结论:

1、 因为你builder 模式使用姿势不对。builder 是静态函数 不需要用实例去调用 , build 之后返回值构造了新的对象 你并没有拿对象去接收。

2、 你没认真调试代码。在第二个打印语句处断点调试,就可以看到附件并没有设置,两个都是null 所以输出 true。

3、没认真看IDE的警告。通过类实例调用静态函数会有警告的。

image.gif

修改一行解决问题:

public class SDemo {
    public static void main(String[] args) {
        Attchment attchment = new Attchment("附件1");
        WeeklyLogByIO logProvious = WeeklyLogByIO.builder().attchment(attchment).build();
        //logProvious.setAttchment(attchment);
        //开始克隆
        WeeklyLogByIO weekNew = null;
        try {
            weekNew = logProvious.deepClone();
        } catch (Exception e) {
            e.printStackTrace();
        }
        weekNew.setDate("第二周");
        System.out.println(logProvious == weekNew);
        System.out.println(logProvious.getAttchment() == weekNew.getAttchment());
    }
}

image.gif

然后该同学表明确实不熟悉 builder 模式,而且不熟悉 lombok。

然后我给出建议:

1、学习Builder模式

2、看 lombok官方文档

3、直接使用反编译工具,查看lombok 注解编译生成的类文件的反编译后的”源码”就可以查看注解对源码的影响。

image.gif

三、看到了什么

3.1 方法的重要性

其实很多人编程过程中遇到问题的主要原因是学习技术不求甚解,大概看看博客,看看别人怎么用就用,没有认真看官方技术文档,没有能够通过更丰富的手段来学习这种技术。

所以很多人想要有较大进步,并不像一些人所想的那样,“更加努力”,而是找到更加科学的方法。

另外我们还看到“很多人觉得某些技术没用,就不愿意学,很多时候正是因为没学好,才在该用到的时候想不着用”。

比如我们可以通过反编译来学习 lombok, 然而很多人想不到用,甚至从来都没尝试过反编译。

3.2 如何提问

另外很多人提问都不是很清楚,对解决问题的人造成很大困难。当然我是希望大家能够自己解决问题,这非常重要,没有人可以一直帮你解决问题,工作之后排错的能力更加重要。

1、提问时要尽可能地有条理表达自己的疑问,带上序号,带上标点,描述清楚前因后果,描述清楚核心困惑等。

2、提问之前自己一定要进行思考,提问之前一定要自己调试过,提问之前一定要自己百度过

3、提问时尽可能给出详细的线索,比如报错的具体内容,比如给出源码,比如 Web 项目 F12看网络给出请求和响应状态等。

3.3 每一个盲点背后

每一个困惑背后至少有一个知识盲区,隐藏着一次极佳的学习机会

该同学通过这个问题的解答,意识到了 builder 设计模式理解不到位,意识到了 lombok 注解了解的不到位。

学到了可以通过反编译来查看 lombok 注解对源码的影响,直观和快速地学习 lombok 注解。

如果是一个聪明的有心人,应该意识到自己解决问题的能力有待提高,自己连起码的断点调试都没有做。

如果是一个聪明的有心人,应该会意识到今后要重视 IDE的警告,甚至安装上推荐的 阿里巴巴 Java 开发规范的配套插件。

如果是一个聪明的有心人,应该可以从我的回答中了解到 commons-lang3 有更简洁地实现序列化和反序列化的工具类,进而了解 commons-lang3 中的其他好用的工具类从而提高开发效率。

如果是一个聪明的有心人,应该能够意识到自己提问的姿势有问题,后续提问应该更有条理,更准确的表达自己的问题。

如果是一个聪明的有心人,应该...

如果真正可以意识到这些问题,并能够较快改正,学习的速度会有极大的提升。

四、总结

希望越来越多的同学能够意识到方法的重要性。

希望也来越多的同学能够知道如何提问。

希望越来越多的同学能够意识到:每一个困惑背后至少有一个知识盲区,隐藏着一次极佳的学习机会 的真正含义。

学习是一种能力,解决问题也是一种能力。

授人以鱼不如授人以渔,同样地,希望大家多学方法,而不是仅仅追求学习某个具体知识点,甚至以记住某个知识点为傲。

-------------------

如果你觉得本文对你有帮助,欢迎点赞、评论、转发(请注明出处)。你的支持是我创作的最大动力。

相关文章
|
敏捷开发 前端开发 开发者
想要成为软件开发中的王者,需要明白的 21 条准则
想要成为软件开发中的王者,需要明白的 21 条准则
|
4月前
|
测试技术
ACL 2024:大模型性能掺水严重?北大交出答卷:交互评估+动态出题,死记硬背也没用
【7月更文挑战第8天】北大研究团队推出KIEval框架,针对大语言模型(LLMs)的性能评估进行创新。KIEval采用互动评估和动态出题,通过多轮基于知识的对话测试模型理解和应用能力,旨在减少数据污染影响,挑战死记硬背的评估。然而,该方法可能增加计算需求,且评估结果可能受主观因素影响,不适用于所有类型LLMs。[论文链接:](https://arxiv.org/abs/2402.15043)**
88 24
|
SQL
工作中的成长是从摆脱低水平勤奋开始的吗?
成长的本质是自我革新,成长就是在不断变化中的积极面。深度思考、目标设定、自律实践、持续学习、总结反思等步骤可以帮助我们成长,同时也需要避免陷入低水平勤奋的陷阱,不要忙于行动而忽视了反思和学习。
144 1
|
安全 架构师 测试技术
【真实感受】超越专业局限,职场人拓展更多可能性!
【真实感受】超越专业局限,职场人拓展更多可能性!
111 0
如何用简单的方式获取C端用户,实力派王素杰说要从B端做起|靠才华
在线教育作为o2o的巨大分支,一个曾经非常显著的优势是提供了新的传播途径。一根网线连接名师和用户,使得老师的个人能力不再局限于地域,用户的学习方式也不再局限于传统课堂。
450 0
还在担心工作要被取代?现实却是机器人已经开始被开除了
短时间内,所谓的“机器人酒店”都是噱头。
348 0
想要搭建陪玩平台,这几点不容忽视
随着互联网经济的持续稳定发展,游戏市场的“封印”逐渐被打开,搭建陪玩平台成为一个新的热点。提起陪玩系统相信大家也不陌生,漫漫单排路如果有一个大神能带自己躺赢那是再好不过了,于是陪玩系统运营而生。想要搭建陪玩平台,应该注意哪些问题呢?