Published on

ARTS 第2周

Authors

Algorithm

Add Two Numbers

package org.nocoder.leetcode.solution;

/**
 * 1.Add Two Numbers
 * 
 * You are given two non-empty linked lists representing two non-negative integers.
 * 
 * The digits are stored in reverse order and each of their nodes contain a single digit.
 * 
 * Add the two numbers and return it as a linked list.
 * 
 * You may assume the two numbers do not contain any leading zero, except the number 0 itself.
 * 
 * Example
 * Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
 * Output: 7 -> 0 -> 8
 * Explanation: 342 + 465 = 807.
 *
 * @author jason
 * @date 18/7/13.
 */
public class AddTwoNumbers {
    public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode listNode = new ListNode(0);
        ListNode cur = listNode;

        int carry = 0;
        while (l1 != null || l2 != null || carry != 0) {
            int val1 = (l1 == null) ? 0 : l1.val;
            int val2 = (l2 == null) ? 0 : l2.val;
            int sum = val1 + val2 + carry;
            cur.next = new ListNode(sum % 10);
            cur = cur.next;
            carry = sum / 10;
            if (l1 != null) {
                l1 = l1.next;
            }
            if (l2 != null) {
                l2 = l2.next;
            }
        }
        return listNode.next;
    }

    public static void main(String[] args) {

        ListNode l1 = new ListNode(2);
        l1.next = new ListNode(4);
        l1.next.next = new ListNode(3);

        ListNode l2 = new ListNode(5);
        l2.next = new ListNode(6);
        l2.next.next = new ListNode(4);

        ListNode.print(l1);
        ListNode.print(l2);
        ListNode.print(AddTwoNumbers.addTwoNumbers(l1, l2));
    }

}

/**
 * Definition for singly-linked list.
 */
class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }

    public static void print(ListNode listNode) {
        while (listNode != null) {
            System.out.print(listNode.val);
            if (listNode.next != null) {
                System.out.print(" -> ");
            }
            listNode = listNode.next;
        }
        System.out.println();
    }
}

Review

Code Review Best Practices https://medium.com/palantir/code-review-best-practices-19e02780015f

  • Why, what, and when to do code reviews Why: 1.个人编程能力提升; 2.知识共享帮助团队提升; 3.代码的一致性; 4.代码的可读性; 5.低级错误和代码结构错误 6.安全 What: 1.团队就自己的方法达成一致; 2.团队中的所有人的代码都需要复查; When: 在自动化检查之后,代码合并到master分支之前进行code review

  • Preparing code for review 1.明确复查范围; 2.提交代码的完整性,确保代码是通过测试和自动化检查的; 3.重构的代码不应该改变其原有的行为意图; 4.人工代码复查重心应该在程序逻辑上,而不是样式、语法或格式,这些问题用自动化工具来检测。

  • Performing code reviews code review的目的、执行、可读性和风格、可维护性、安全、评论以及认真回复review评论。

  • Code review examples

Inconsistent naming 命名风格不一致

class MyClass {
  private int countTotalPageVisits; //R: name variables consistently
  private int uniqueUsersCount;
}

Inconsistent method signatures 方法签名不一致

interface MyInterface {
  /** Returns {@link Optional#empty} if s cannot be extracted. */
  public Optional<String> extractString(String s);
  /** Returns null if {@code s} cannot be rewritten. */
  //R: should harmonize return values: use Optional<> here, too
  public String rewriteString(String s);
}

Library use 使用工具类

//R: remove and replace by Guava's MapJoiner
String joinAndConcatenate(Map<String, String> map, String keyValueSeparator, String keySeparator);

Personal taste

int dayCount; //R: nit: I usually prefer numFoo over fooCount; up to you, but we should keep it consistent in this project

Bugs

//R: This performs numIterations+1 iterations, is that intentional?
//   If it is, consider changing the numIterations semantics?
for (int i = 0; i <= numIterations; ++i) {
  ...
}

Architectural concerns 架构问题

otherService.call(); //R: I think we should avoid the dependency on OtherService. Can we discuss this in person?

Tip

上周在写一个定时删除无用资源的定时任务,用到了列举所有oss对象的方法,阿里的FAQ回复有勘误(已向他们反馈,现已修复)

获取阿里云OSS上指定bucket下所有的对象信息列表

String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
String bucketName = "<yourBucketName>";
// 创建OSSClient实例。
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
final int maxKeys = 200;
String nextMarker = null;
ObjectListing objectListing;
do {
    objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withMarker(nextMarker).withMaxKeys(maxKeys));
    List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
    for (OSSObjectSummary s : sums) {
        System.out.println("\t" + s.getKey());
    }
    nextMarker = objectListing.getNextMarker();
} while (objectListing.isTruncated());
// 关闭OSSClient。
ossClient.shutdown();

Share

20条数据库设计最佳实践

https://dzone.com/articles/20-database-design-best

  1. tablecolumn使用明确定义的单词并且风格一致的命名。
  2. 表名使用单数(例如:使用StudentCourse 而不是StudentCourses),table代表着一个实体的集合,不需要用复数命名。
  3. 表名不要用空格,否则,您将不得不使用'{','[','''等字符来定义表,访问时还需要用引号“Student Course”, 直接用StudentCourse会更好。
  4. 表名不要使用不必要的前缀或者后缀,例如使用School而不是TblSchool, SchoolTable
  5. 保持密码的安全性,需要用的时候在程序里解密
  6. 所有表使用integer类型ID字段。 即使暂时不需要ID,将来也可能会需要,例如关联表,索引等。
  7. 索引选择integer类型的列,varchar列索引会引起性能问题。
  8. 使用位字段存储布尔值,使用integervarchar是不必要的存储消耗。布尔值的字段列命名使用is作为前缀。
  9. 提供数据库访问权限,不要把管理员权限分配给所有人。
  10. 尽量避免出现select * 查询除非必须需要,使用select [需要的列]可以提高查询效率。
  11. 如果应用程序代码足够大,则使用ORM(object relational mapping)框架(例如 hibernateMyBatis ...)。ORM框架的性能问题可以通过详细的配置参数来处理。
  12. 将大表、不用的表或很少使用的表,部分划分到不同的物理存储区以提高查询性能。
  13. 对于大型,敏感和任务评论者数据库系统,使用灾难恢复和安全服务,如故障转移群集,自动备份,复制等。
  14. 使用约束(外键,检查,非空...)来保证数据的完整性。 不要把所有的控制权都交给程序代码处理。
  15. 缺乏数据库文档是非常可恶的。 用ER图和说明文档来记录数据库设计。 也为触发器,存储过程和其他脚本编写注释行。
  16. 在大表上经常使用的查询创建索引。 分析工具可以用来确定需要定义哪些索引。 对于多行数据的查询,聚簇索引通常更好。 对于点查询,非聚集索引通常更好。
  17. 数据库服务器和Web服务器必须放置在不同的机器上。 这将提供更高的安全性(攻击者无法直接访问数据),并且由于请求数量和进程使用率降低,服务器CPU和内存性能会更好。
  18. 由于性能问题,不得在频繁查询的表中定义图像和Blob数据列。 这些数据必须放在单独的表中,并且它们的指针可以在查询的表中使用。
  19. 标准化必须根据需要使用,以优化性能。 欠规范化会导致数据的过度重复,过度规范化会导致太多表中的过多连接。两者都会影响性能。
  20. 一定要为数据库设计留足够的时间,否则可能会花费比设计多成百上千倍的时间来维护设计不佳的数据库甚至需要重新设计。