Tuesday, February 12, 2019

AWS RDS



Cluster parameter
server_audit_logging
server_audit_events (QUERY)

它包括了Instance parameter的所有参数
slow_query_log
general_log

修改parameter group不能用default,因为default不能修改

还可以将logs发布到cloudwatch

怎么用workbench连RDS实例:

Sunday, February 10, 2019

React 简介

React引入是解决网站由于数据更新而重新刷新页面的效率问题。它比较数据变化引起的页面变化(page diff)而只刷新相应的前端,从而大大提高效率。

JSX

JSX是React发明的类型,
<script type="text/jsx">
      // ** Our code goes here! **
 </script>

HTML 语言直接写在 JavaScript 语言之中,不加任何引号。遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。
var arr = [
  <h1>Hello world!</h1>,
  <h2>React is awesome</h2>,
];
React.render(
  <div>{arr}</div>,
  document.getElementById('example')
);

React.render()

React.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点(第二个参数)。

this.props 和 this.state 

this.props 对象的属性与组件的属性一一对应。由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义如href,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性(用户输入)。

var LikeButton = React.createClass({
  getInitialState: function() {
    return {liked: false};
  },
  handleClick: function(event) {
    this.setState({liked: !this.state.liked});
  },
  render: function() {
    var text = this.state.liked ? 'like' : 'haven\'t liked';
    return (
      <p onClick={this.handleClick}>
        You {text} this. Click to toggle.
      </p>
    );
  }
});

React.render(
  <LikeButton />,
  document.getElementById('example')
);

这个LikeButton是一个接受空参数的组件。若需要输入参数到组件,请见组件间通信。

Redux

Redux是网站的cache层,用来保存组件状态。使用场景:
某个组件的状态,需要共享
某个状态需要在任何地方都可以拿到
一个组件需要改变全局状态

各组件之间的通信用state(Redux)作为媒介。这是在传统上新加的抽象层,也就是HTML和JS之间加入Redux层用状态传递。Action是变化obj,Reducer是biz逻辑处理函数,输入是previous state, Action,输出是new state。

Lifecycle


Mounting: component加到DOM.
Updates: component接收props或state改动,component重新render.
Unmounting: component从DOM中删除

经常需要更新的组件就放在updates,static的部分就在mounting。

componnetWillReceiveProps(nextProps) {
    this.setState({selectedOptions: nextProps.selectedOptions});
}
可以将props的改变放入到state里面从而re-render

React Table

import ReactTable from 'react-table'

render() {
  const data = [{
    name: 'Tanner Linsley',
    age: 26,
    friend: {
      name: 'Jason Maurer',
      age: 23,
    }
  },{
    ...
  }]

  const columns = [{
    Header: 'Name',
    accessor: 'name' // String-based value accessors!
  }, {
    Header: 'Age',
    accessor: 'age',
    Cell: props => <span className='number'>{props.value}</span> // Custom cell components!
  }]

  return <ReactTable
    data={data}
    columns={columns}
  />
}

Component

组件概念:就是为了可以复用,提供定制化参数如css classname, 输入数据。
如filtered-multiselect提供onchange函数定制,options列表等。可以把它封装成一个自定义component提供给自己网站的其他网页使用。类似的组件还有data range picker网上很多开源的组件并不需要自己造。
     <FilteredMultiSelect
        onChange={this.handleSelectionChange}
        options={CULTURE_SHIPS}
        selectedOptions={selectedShips}
        textProp="name"
        valueProp="id"
      />

组件间的通信

父向子,就是调用子组件时就会提供参数到其构造函数

 return <ReactTable
    data={data}
    columns={columns}
  />


ReactTable.propTypes = {
   data: PropTypes.array.isRequired,
   columns: PropTypes.array.isRequired,
}
怎么用
console.log(this.props.data);


子向父,通过绑定父和子函数实现,如例子中绑定子组件的onSave和父组件的handleSave。通过此句来实现。当子组件的状态变化(用户输入),就会触发父组件写入其另一个Li的子组件中。
<InputAndButton onSave={this.handleSave.bind(this)}/>


handleSave(text){ 
        if(text.length !== 0){
            this.state.items.push({key: new Date().getTime(), text});  
            this.setState({
                items: this.state.items,
            })
        }
    };

<InputAndButton
     title="abc"
     onSave={this.handleSave.bind(this)}/>  

this.props.onSave(this.state.inputValue.trim());
console.log(this.props.title); //输入参数值

InputAndButton.defaultProps = {
   title: 'Button';
};

InputAndButton.propTypes = {
    title: PropTypes.string,
    title: PropTypes.string.isRequired,
};

propTypes是这个表示这个组件构造函数的输入参数,defaultProps表示默认值。注意如果父子孙三重关系,可以将子的props传入孙中,不要在子中奖props赋值到state然后将state传到孙,这样state会出现不sync。

in-style css
style={{marginLeft: 40}}

Ref
ReactJS简介
React简书
Redux
Life cycle
组件通信
React table
React filtered multiselect
React data range picker

Mutation Test 简介

Unit test的Line coverage很容易达到100%,但是并不能衡量测试的质量。Mutation test的引入就是解决这个问题。它通过修改程序然后跑现有的tests,如果tests没有fail的话,表示mutation coverage不好,所以mutation test是反着(每次否定一个语句)来跑测试的。Java的mutation test的框架主要是Pitest。

概念

Mutant: 每一个代码改动
Mutation: 修改了的程序
Killed: 一个mutation不能通过unit test,这叫此mutation被杀死了,这是我们想见到的。
Survived: 一个mutation还能通过unit test,这叫此mutation存活了。

下面这个程序是判断一个字符串是否Palindrome。用首尾字符比较然后向中心字符串递归。
public boolean isPalindrome(String inputString) {
    if (inputString.length() == 0) {
        return true;
    } else {
        char firstChar = inputString.charAt(0);
        char lastChar = inputString.charAt(inputString.length() - 1);
        String mid = inputString.substring(1, inputString.length() - 1);
        return (firstChar == lastChar)
                     && isPalindrome(mid);
    }
}

Unit test如下,它的code coverage是100%,但是它mutation coverage只有6/8。它两个地方没有被NEGATE_CONDITIONALS_MUTATOR杀死。

@Test
public void whenPalindrom_thenAccept() {
    Palindrome palindromeTester = new Palindrome();
    assertTrue(palindromeTester.isPalindrome("noon"));
}

第一处,若程序修改成  if (inputString.length() != 0),单元测试仍可以通过,因为任何非空字符串包括noon直接返回true了。这表示我们缺少failure test,加入下面这个:
@Test
public void whenNotPalindrom_thanReject() {
    Palindrome palindromeTester = new Palindrome();
    assertFalse(palindromeTester.isPalindrome("box"));
}

加入了第二个测试后。第二处,也就是程序改成&& !isPalindrome(mid),仍然survived,比较tricky。oo -->false,  noon->true & !f(oo)= true, 双重否定后仍然是成立。所以加入只有有一组首尾相等的测试如neon即可。
@Test
public void whenNearPalindrom_thanReject() {
    Palindrome palindromeTester = new Palindrome();
    assertFalse(palindromeTester.isPalindrome("neon"));
}

Mutator

包括7个默认的Mutator
Conditionals Boundary Mutator。 如<= to < 
Increments Mutator。如i++ to i--
Invert Negatives Mutator。如return i to return -i
Math Mutator。如b+c to b-c
Negate Conditionals Mutator。如== to !=,这个是最普遍的会survive的。
Return Values Mutator。如return new Object() to return null
Void Method Calls Mutator。如someMethod() to (method removed)。这个也普遍。

其他Mutator
Constructor Call Mutator。如Object o = new Object to Object o = null
Empty returns Mutator。如return "abc" to return ""


Config

--threads表示用多少个线程跑
--mutators用什么mutator
--coverageThreshold测试覆盖率
--targetClasses只测试某个包下面的class
--targetTests只测试某个TestClass
--timeoutConst某个测试的时间上限。这个影响全部测试的时间,因为有些mutation可能会导致死循环,当然也算是failed的。

Incremental Analysis

可以配置来减少每次跑测试的时间。因为通过比较代码改动和上次测试结果,新一轮测试只会incremental跑。


Ref

http://pitest.org/quickstart/mutators/
https://www.baeldung.com/java-mutation-testing-with-pitest
https://www.testwo.com/article/869