当前位置:   article > 正文

每一个疑问背后都隐藏着至少一个盲点和学习的绝佳机会_每一道题都击中了我的知识盲点

每一道题都击中了我的知识盲点

一、背景

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

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

今天有一个朋友问到:

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

二、解答过程

2.1 存在的问题

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

2.2 引导

因此给出下面的回复:

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

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

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

比如

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

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

给出的进一步建议:

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

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

然后该同学发来了代码:

附件类:

  1. import java.io.Serializable;
  2. @Data
  3. @AllArgsConstructor
  4. public class Attchment implements Serializable {
  5. private String name;
  6. }

待测试类:

  1. import lombok.AllArgsConstructor;
  2. import lombok.Builder;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. import java.io.*;
  6. @Data
  7. @Builder
  8. @NoArgsConstructor
  9. @AllArgsConstructor
  10. public class WeeklyLogByIO implements Serializable {
  11. private String name;
  12. private String date;
  13. private String content;
  14. private Attchment attchment;
  15. public WeeklyLogByIO deepClone() throws Exception{
  16. //将对象写入到流中
  17. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  18. ObjectOutputStream oos = new ObjectOutputStream(bos);
  19. oos.writeObject(this);
  20. //将对象从流中取出
  21. ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
  22. ObjectInputStream ois = new ObjectInputStream(bis);
  23. return (WeeklyLogByIO)ois.readObject();
  24. }
  25. }

测试代码:

  1. public class SDemo {
  2. public static void main(String[] args) {
  3. WeeklyLogByIO logProvious = new WeeklyLogByIO();
  4. Attchment attchment = new Attchment("附件1");
  5. logProvious.builder().attchment(attchment).build();
  6. //logProvious.setAttchment(attchment);
  7. //开始克隆
  8. WeeklyLogByIO weekNew = null;
  9. try {
  10. weekNew = logProvious.deepClone();
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. }
  14. weekNew.setDate("第二周");
  15. System.out.println(logProvious == weekNew);
  16. System.out.println(logProvious.getAttchment() == weekNew.getAttchment());
  17. }
  18. }

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

和对方确认他的表达:

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

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

看了DEMO 得出了两个结论:

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

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

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

修改一行解决问题:

  1. public class SDemo {
  2. public static void main(String[] args) {
  3. Attchment attchment = new Attchment("附件1");
  4. WeeklyLogByIO logProvious = WeeklyLogByIO.builder().attchment(attchment).build();
  5. //logProvious.setAttchment(attchment);
  6. //开始克隆
  7. WeeklyLogByIO weekNew = null;
  8. try {
  9. weekNew = logProvious.deepClone();
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. }
  13. weekNew.setDate("第二周");
  14. System.out.println(logProvious == weekNew);
  15. System.out.println(logProvious.getAttchment() == weekNew.getAttchment());
  16. }
  17. }

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

然后我给出建议:

1、学习Builder模式

2、看 lombok官方文档

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

三、看到了什么

3.1 方法的重要性

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

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

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

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

3.2 如何提问

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

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

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

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

3.3 每一个盲点背后

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

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

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

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

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

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

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

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

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

四、总结

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

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

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

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

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/386166
推荐阅读
相关标签
  

闽ICP备14008679号