一次平平无奇的UDP维修过程

本文讲述了作者作为一名存储行业从业者,如何通过分析和动手修复一个无法识别的U盘,过程中涉及X-RAY检查、元件更换等技术细节,最终成功恢复重要数据的故事。同时,作者也认识到自身在硬件知识上的不足,并强调重要数据应多备份的重要性。

1 背景

  • 春节前拷贝工作资料到U盘中,随手把U盘一拔,然后下次使用的时候,发现电脑没有 任何反应,在资源管理器中找不到对应设备。
  • 想起来U盘中某某嵌套文件夹珍藏的学习资料,心情不免悲痛。
  • 我作为一个存储行业从业者,决心解决这个问题。
  • U盘是下面这种,上面写着"以换代修",后面拆开外壳才知道为什么要写着"以换代修",因为维修难度和费用高。
    图1.1 U盘商品截图

2 初步分析

  • 回到公司使用仪器测量上盘电流,发现完全无反应。

  • 拆金属外壳,厂商放了很多胶水,过程费劲。用高温枪加热,然后剪开一点外壳,用镊子可以取出。拆开如下图,果然是黑胶体封装,感觉希望渺茫。
    图2.1 拆去外壳的黑胶体封装

  • 尝试短接上述两个点进入BOOT mode,上盘还是没有电流。

3 方案

  • 由于里面数据很重要,所以只能进一步分析,想到了两个方案。

3.1 换料

  • 首先X-Ray,看下U盘内部是否有明显问题。运气好的话,主控没有烧坏、多层板中间层的导线没有断裂。
  • 如果只是电容、电阻坏了,那么decap更换即可。

3.2 换NAND

  • 如果上述办法解决不了,想着采购一个同款U盘,把失效U盘的NAND换过去。
  • 但是U盘购买时间较久,可能当前购买的批次对应的主控和基板都不一样,而且如果NAND是裸die,更换风险和技术要求还是很高的。

4 实施

  • 联系到相关工厂,驱车过去现场分析。

4.1 X-RAY

  • X-Ray看到打线、导线没有问题
  • 但是右下角有个元件比较奇特,X-Ray直接透过去了,换了角度去看也不知道是什么。因为没有对比的样品,也不好确认是否有问题。
  • 下图为X-Ray打线特写
    图4.1 打线特写
  • 下图为X-Ray整体,右下角未知元件
    图4.2 X-Ray整体,右下角未知元件
  • 下图为右下角未知元件特写图4.3 右下角未知元件特写
    • 下图为右下角未知元件侧面特写图4.4 右下角未知元件侧面特写

4.2 DECAP

  • 对右下角那个元件进行开盖,看外观是一个电阻,量测已经断路了。
  • 万用表量测其它元件,没有发现问题

4.3 换料

  • 使用0欧姆电阻替换右下角失效的元件
  • Decap换料后的情况
    图4.5 Decap换料后情况
  • 插入电脑,U盘有电流,可以成功上盘。狂喜,赶紧拷贝出重要的数据。
  • 发现读取部分很久之前存放的数据时会出错,查看文件已经乱码。可能是高温枪加热取外壳和Data retenion导致NAND Flash出错。但是最重要的数据已经拷贝出来了,已经非常幸运。

5 总结

  • 经过这次经历,发现我作为固件开发者,在硬件上知识的欠缺,后续学习相关知识。
  • 不要太相信购买到U盘的可靠性和稳定性,重要数据记得多备份。
在Java开发中,一些看似简单的代码片段可能隐藏着严重的潜在问题,这些问题可能在短期内不会暴露,但一旦发生,往往会造成难以排查的后果。以下是一些常见的简单但容易引发问题的Java代码示例。 ### 3.1 单例模式中的双重检查锁定问题 在实现单例模式时,为了提高性能,开发者常使用双重检查锁定(Double-Checked Locking)模式。然而,如果不正确使用 `volatile` 关键字,可能会导致线程安全问题。 ```java public class LazySingleTon { private static LazySingleTon instance = null; private LazySingleTon(){} public static LazySingleTon getInstance() { if(instance == null){ synchronized (LazySingleTon.class){ if(instance == null){ instance = new LazySingleTon(); } } } return instance; } } ``` 在上述代码中,`instance` 没有使用 `volatile` 修饰,这可能导致指令重排序的问题,从而导致某些线程看到一个未完全构造的实例。为了防止这种问题的发生,应该使用 `volatile` 来修饰 `instance` 变量[^4]。 ### 3.2 使用 `ConcurrentHashMap` 时的复合操作问题 虽然 `ConcurrentHashMap` 是线程安全的集合类,但在执行一些复合操作时,仍然需要额外的同步机制来保证原子性。 ```java public class Cache<K, V> { private final ConcurrentHashMap<K, V> cache = new ConcurrentHashMap<>(); public V get(K key) { return cache.get(key); } public void put(K key, V value) { cache.put(key, value); } // 复合操作需要保证原子性 public V putIfAbsent(K key, V value) { V existing = cache.get(key); if (existing == null) { existing = value; cache.put(key, value); } return existing; } } ``` 在上述代码中,`putIfAbsent` 方法是一个复合操作,包含检查和更新两个步骤。由于 `ConcurrentHashMap` 不保证复合操作的原子性,多个线程同时调用该方法可能会导致数据不一致的问题。因此,应该使用 `ConcurrentHashMap` 提供的原子方法 `putIfAbsent` 来替代自定义实现[^5]。 ### 3.3 ABA 问题 在使用 `CAS`(Compare and Set)操作时,可能会遇到 ABA 问题。这个问题指的是一个值从 A 变成 B,又变回 A,此时 `CAS` 操作会认为该值没有发生变化,但实际上中间已经发生了修改。 ```java AtomicReference<Integer> atomicReference = new AtomicReference<>(1); new Thread(() -> { atomicReference.compareAndSet(1, 2); atomicReference.compareAndSet(2, 1); }).start(); new Thread(() -> { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } boolean success = atomicReference.compareAndSet(1, 3); System.out.println("CAS success: " + success); }).start(); ``` 在上述代码中,第一个线程将 `atomicReference` 的值从 1 改为 2,然后再改回 1。第二个线程在执行 `CAS` 操作时会成功,因为它无法感知到中间的变化。为了解决这个问题,可以使用 `AtomicStampedReference` 来为每次修改添加版本号,从而区分值是否真正发生变化[^3]。 ### 3.4 类型转换问题 在进行类型转换时,如果不进行类型检查,可能会导致 `ClassCastException`。 ```java Object obj = "Hello"; Integer i = (Integer) obj; // 抛出 ClassCastException ``` 在上述代码中,`obj` 是一个 `String` 类型的对象,尝试将其强制转换为 `Integer` 类型会导致运行时异常。为了避免此类问题,可以在转换前使用 `instanceof` 进行类型检查。 ```java if (obj instanceof Integer) { Integer i = (Integer) obj; } ``` ### 3.5 异常处理不当 在捕获异常时,如果直接捕获 `Exception` 或 `Throwable`,而没有进行适当的处理,可能会掩盖潜在的问题。 ```java try { // 可能抛出异常的代码 } catch (Exception e) { // 忽略异常 } ``` 在上述代码中,所有异常都被捕获并忽略,导致问题无法及时发现。正确的做法是捕获特定的异常,并记录日志或采取适当的恢复措施。 ```java try { // 可能抛出异常的代码 } catch (IOException e) { e.printStackTrace(); } ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值