- Published on
ARTS 第37周
- Authors
- Name
- Jason Yang
- @yangjinlong86
- Algorithm: 942. DI String Match
- Review: What is Test Driven Development (TDD)
- Tip: Springboot logback profile
- Share: 阮一峰的每周分享第52期
Algorithm
package org.nocoder.leetcode.solution;
/**
* 942. DI String Match
* <p>
* Given a string S that only contains "I" (increase) or "D" (decrease), let N = S.length.
* <p>
* Return any permutation A of [0, 1, ..., N] such that for all i = 0, ..., N-1:
* <p>
* If S[i] == "I", then A[i] < A[i+1]
* If S[i] == "D", then A[i] > A[i+1]
* <p>
* <p>
* Example 1:
* <p>
* Input: "IDID"
* Output: [0,4,1,3,2]
* Example 2:
* <p>
* Input: "III"
* Output: [0,1,2,3]
* Example 3:
* <p>
* Input: "DDI"
* Output: [3,2,0,1]
* <p>
* <p>
* Note:
* <p>
* 1 <= S.length <= 10000
* S only contains characters "I" or "D".
*
* @author jason
* @date 2019/4/28.
*/
public class DIStringMatch {
public static int[] diStringMatch(String s) {
int n = s.length();
int lo = 0, hi = n;
int[] ans = new int[n + 1];
for (int i = 0; i < n; ++i) {
if (s.charAt(i) == 'I') {
ans[i] = lo++;
} else {
ans[i] = hi--;
}
}
ans[n] = lo;
return ans;
}
public static void main(String[] args) {
int[] arr = diStringMatch("IDID");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
Review
What is Test Driven Development (TDD)?
测试驱动开发从为应用程序的每个小功能设计和开发测试开始。在TDD方法中,首先,开发测试,指定并验证代码将执行的操作。
如何进行TDD测试
以下步骤定义了如何执行TDD
- 编写测试代码
- 运行所有测试,看看是否有任何新测试失败
- 编写业务逻辑代码
- 运行测试并重构代码
- 重复以上过程
关于TDD的一些说明:
- TDD既不是“测试”也不是“设计”。
- TDD并不意味着“编写一些测试,然后构建一个通过测试的系统。
- TDD并不意味着“进行大量测试”。
Tip
Springboot logback profile
Springboot 默认的logging 配置可以将日志打印到控制台或者写出到文件,如果需要滚动归档,就可以用
logback.xml
来扩展日志功能了, 接下来我们需要实现不同的环境不同的日志配置,例如开发环境下直接打印到控制台,测试环境下打印日志到控制台并且输出到文件,生产环境只输出到文件。
在Resource
目录下创建xml配置文件,这样命名logback-spring.xml
官方的控制台打印日志配置了颜色,比较好看,可以引入springboot logging 包下的defaults.xml直接使用
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>./log/service-keeper.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level %logger{5} - %msg%n</pattern>
<charset class="java.nio.charset.Charset">UTF-8</charset>
</encoder>
</appender>
<springProfile name="dev">
<logger name="org.nocoder.servicekeeper.infrastructure.repository" level="DEBUG"/>
<root level="info">
<appender-ref ref="CONSOLE"/>
<!--<appender-ref ref="FILE"/>-->
</root>
</springProfile>
<springProfile name="test">
<logger name="org.nocoder.servicekeeper.infrastructure.repository" level="DEBUG"/>
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</springProfile>
<springProfile name="prod">
<root level="info">
<appender-ref ref="FILE"/>
</root>
</springProfile>
</configuration>
org/springframework/boot/logging/logback/defaults.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Default logback configuration provided for import, equivalent to the programmatic
initialization performed by Boot
-->
<included>
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
<logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
<logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
<logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/>
<logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/>
<logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/>
<logger name="org.hibernate.validator.internal.util.Version" level="WARN"/>
</included>
application.yml
spring:
profiles:
active: dev
配置好以后Resource 目录下的结构类似这样
└── resources
├── application-dev.yml
├── application-prod.yml
├── application-test.yml
├── application.yml
├── logback-spring.xml