Bootstrap

ARTS打卡Week 06

每周完成一个 ARTS:

Algorithm: 每周至少做一个 LeetCode 的算法题

Review: 阅读并点评至少一篇英文技术文章

Tips: 学习至少一个技术技巧

Share: 分享一篇有观点和思考的技术文章

Algorithm

/*
 Runtime: 7 ms, faster than 6.43% of Java online submissions for Binary Tree Level Order Traversal.
 Memory Usage: 40.8 MB, less than 5.44% of Java online submissions for Binary Tree Level Order Traversal.
 */
static class Solution1 {
  public List> levelOrder(TreeNode root) {
    List> answer = new ArrayList<>();
    if (root == null) {
      return answer;
    }
    Queue queue = new ArrayDeque<>();
    queue.offer(root);

    while (queue.size() != 0) {
      List levelAnswer = new ArrayList<>();
      List levelNode = new ArrayList<>();
      for (TreeNode node : queue) {
        levelAnswer.add(node.val);
        if (node.left != null) {
          levelNode.add(node.left);
        }
        if (node.right != null) {
          levelNode.add(node.right);
        }
      }
      queue.clear();
      queue.addAll(levelNode);
      answer.add(levelAnswer);
    }
    return answer;
  }
}

/*
 Runtime: 2 ms, faster than 16.72% of Java online submissions for Binary Tree Level Order Traversal.
 Memory Usage: 40.7 MB, less than 8.69% of Java online submissions for Binary Tree Level Order Traversal.
 */
static class Solution2 {
  public List> levelOrder(TreeNode root) {
    List> answer = new ArrayList<>();
    if (root == null) {
      return answer;
    }
    Queue queue = new ArrayDeque<>();
    queue.offer(root);

    // 避免queue的addAll操作
    while (queue.size() != 0) {
      List levelAnswer = new ArrayList<>();
      int qSize = queue.size();
      for (int i = 0; i < qSize; i++) {
        TreeNode tempNode = queue.poll();
        levelAnswer.add(tempNode.val);
        if (tempNode.left != null) {
          queue.offer(tempNode.left);
        }
        if (tempNode.right != null) {
          queue.offer(tempNode.right);
        }
      }
      answer.add(levelAnswer);
    }
    return answer;
  }
}

/*
 Runtime: 1 ms, faster than 60.85% of Java online submissions for Binary Tree Level Order Traversal.
 Memory Usage: 40.7 MB, less than 7.08% of Java online submissions for Binary Tree Level Order Traversal.
 */
static class Solution3 {
  public List> levelOrder(TreeNode root) {
    List> answer = new ArrayList<>();
    if (root == null) {
      return answer;
    }
    // queue实现换成LinkedList
    Queue queue = new LinkedList<>();
    queue.offer(root);

    while (queue.size() != 0) {
      List levelAnswer = new ArrayList<>();
      int qSize = queue.size();
      for (int i = 0; i < qSize; i++) {
        TreeNode tempNode = queue.poll();
        levelAnswer.add(tempNode.val);
        if (tempNode.left != null) {
          queue.offer(tempNode.left);
        }
        if (tempNode.right != null) {
          queue.offer(tempNode.right);
        }
      }
      answer.add(levelAnswer);
    }
    return answer;
  }
}

Review

本周阅读了ios的storekit文档,体会到iOS的文档体系并不比Android好到哪里去。甚至更麻烦。

在开发时,碰到一个“Cannot connect to iTunes Store”问题,看文档、翻论坛,都找不到准确的解决方案。并且iOS无法看到storekit源码,一切解决方案都是靠猜。论坛里的解决方案也是充满玄学味道。

作为一个Android开发者,对这点很不习惯。

Tips

本周学习到了一个iOS界面屏幕适配技巧。

我的业务场景是,有一个界面,界面元素宽高、间距会根据不同设备不同。与一位iOS同事请教后,对这个界面的UI代码做了如下重构:

如宽度、高度:

#define scaleWidthRatio      UIScreen.mainScreen.bounds.size.width / 375.0

- (CGFloat)getBannerHeight {
    return 280 * scaleWidthRatio;
}

间距:

- (CGFloat)getFeatureViewBottom {
    if ([Utility iPhoneX]) {
        return -60.0;
    } else if (IS_SCREEN_WIDTH_414()) {
        return -21.0;
    } else {
        return -20.0;
    }
}

Share

《程序员修炼之道-第二版》优秀设计精髓一章阅读感悟:ETC与设计原则(模式)的关系是什么?

书中讲到优秀设计的精髓是ETC(更容易变更)。设计原则则是ETC的一个特例。比如,为什么单一职责很有用?因为一个需求变化仅体现为某个单一模式上的一个对应变化 --- 这就是ETC啊。

针对其它设计原则,我们也来看一看为什么它们的本质也是ETC。

开闭原则(OCP):设计良好的计算机软件应该易于扩展,同时抗拒修改。

易于扩展本质上就是对变更的应对 -- 此谓ETC。

里氏替换原则(LSP):子类型替换不影响原有程序。

License会根据不同子类型计算授权费用。上述设计符合LSP。这种设计使得对License的扩展更容易,对Personal License和Business License的修改也更容易。 -- 此谓ETC

依赖反转原则(DIP):如果想要设计一个灵活的系统,在源代码层次的依赖关系中就应该多引用抽象类型,而非具体实现。

源码之间引用具体实现,会导致后续维护变得困难(更多的代码修改,意味着更高成本和风险)。反之,符合DIP的设计,也谓ETC。

接口隔离原则(ISP):任何层次的代码,不应依赖它不使用的方法。

依赖不使用的方法,就意味着关注焦点被扩大,会“注意力分散”,分散的后果,就是当这些方法变更时,可能会导致“被变更”,从而引入不稳定风险。反之,隔离关注焦点,可让每一部分都容易变更 -- 此谓ETC。

从上述分析我们可以得到一个认识是:ETC是软件设计的一个基本价值观。当它具体表现在架构设计领域时,每一个设计原则,都是符合ETC的。