2016年4月简讯

工作方面:
这个月最主要的工作就是把Oracle测试跑完了,我接手跑了2个月,加上另一位同事的工作,前后将近8个月,真可以称得上是“旷日持久”了。期间最大的收获就是对Oracle入门了,另外也把docker的知识做了巩固。下一步的任务是SAP HANA。感觉SAP HANA的相关资料太少了,只能一点一点摸索了。

业余时间:
几乎全部花在了Golang上面:月初写了两个小packagestackqueue,而最近受到一位印度工程师的启发,开始着手写一个Golang 101 Hacks系列。写这个系列的原因并不是自己对Golang有多了解,而这个过程恰恰是一个很好的学习经历,可以巩固和加深自己对Golang语言知识点理解。希望自己可以坚持下去。

 

什么是SAP BW和SAP BW-EML?

SAP BWSAP Business Warehouse的缩写。Data warehouse用来存储数据,而SAP BW则是data warehouse加上一些工具,这些工具用来对data warehouse中的数据进行操作,产生一些有用的信息。

SAP BW-EML则代表SAP BW Enhanced Mixed Load Benchmark,一个度量性能的标准。

参考资料:
What is SAP BW and what is it used for?
Behind the SAP BW-EML Benchmark

 

Go语言实践技巧(10)——type literal

根据Go语言规范

A type determines the set of values and operations specific to values of that type. Types may be named or unnamed. Named types are specified by a (possibly qualified) type name; unnamed types are specified using a type literal, which composes a new type from existing types.

可以理解为,unnamed types就被称作type literal

 

Go语言实践技巧(9)——计算时间差

这个技巧来自:https://twitter.com/davecheney/status/718020797734866944。计算时间差的代码如下:

package main
import (
    "time"
    "fmt"
)

func main()  {
    t1 := time.Now()
    time.Sleep(5 * time.Second)
    fmt.Println(time.Since(t1))
} 

执行结果如下:

5.0005s

time.Since(t)time.Now().Sub(t)shorthand.

 

Go语言的interface

以下摘自The Go Programming Language

An interface is an abstract type. It doesn’t expose the representation or internal structure of its values, or the set of basic operations they support; it reveals only some of their methods. When you have a value of an interface type, you know nothing about what it is; you know only what it can do, or more precisely, what behaviors are provided by its methods.

For each named concrete type T, some of its methods have a receiver of type T itself whereas others require a *T pointer. Recall also that it is legal to call a *T method on an argument of type T so long as the argument is a variable; the compiler implicitly takes its address. But this is mere syntactic sugar: a value of type T does not possess all the methods that a *T pointer does, and as a result it might satisfy fewer interfaces.

interface{}, which is called the empty interface type, is indispensable. Because the empty interface type places no demands on the types that satisfy it, we can assign any value to the empty interface.

Since interface satisfaction depends only on the methods of the two types involved, there is no need to declare the relationship between a concrete type and the interfaces it satisfies. That said, it is occasionally useful to document and assert the relationship when it is intended but not otherwise enforced by the program.

Conceptually, a value of an interface type, or interface value, has two components, a concrete type and a value of that type. These are called the interface’s dynamic type and dynamic value.

For a statically typed language like Go, types are a compile-time concept, so a type is not a value. In our conceptual model, a set of values called type descriptors provide information about each type, such as its name and methods. In an interface value, the type component is represented by the appropriate type descriptor.

An interface value is described as nil or non-nil based on its dynamic type. You can test whether an interface value is nil using w == nil or w != nil. Calling any method of a nil interface value causes a panic.

In general, we cannot know at compile time what the dynamic type of an interface value will be, so a call through an interface must use dynamic dispatch. Instead of a direct call, the compiler must generate code to obtain the address of the method from the type descriptor, then make an indirect call to that address. The receiver argument for the call is a copy of the interface’s dynamic value.

Interface values may be compared using == and !=. Two interface values are equal if both are nil, or if their dynamic types are identical and their dynamic values are equal according to the usual behavior of == for that type. Because interface values are comparable, they may be used as the keys of a map or as the operand of a switch statement.

However, if two interface values are compared and have the same dynamic type, but that type is not comparable (a slice, for instance), then the comparison fails with a panic.

A type assertion is an operation applied to an interface value. Syntactically, it looks like x.(T), where x is an expression of an interface type and T is a type, called the “asserted” type. A type
assertion checks that the dynamic type of its operand matches the asserted type.

There are two possibilities. First, if the asserted type T is a concrete type, then the type assertion checks whether x’s dynamic type is identical to T. If this check succeeds, the result of the type assertion is x’s dynamic value, whose type is of course T. In other words, a type assertion to a concrete type extracts the concrete value from its operand. If the check fails, then the operation panics.

Second, if instead the asserted type T is an interface type, then the type assertion checks whether x’s dynamic type satisfies T. If this check succeeds, the dynamic value is not extracted; the result is still an interface value with the same type and value components, but the result has the interface type T. In other words, a type assertion to an interface type changes the type of the expression, making a different (and usually larger) set of methods accessible, but it preserves the dynamic type and value
components inside the interface value.

No matter what type was asserted, if the operand is a nil interface value, the type assertion fails. A type assertion to a less restrictive interface type (one with fewer methods) is rarely needed, as it behaves just like an assignment, except in the nil case.

Go语言的method

以下摘自The Go Programming Language

Either the receiver argument has the same type as the receiver parameter, for example both have type T or both have type *T:

Point{1, 2}.Distance(q) // Point
pptr.ScaleBy(2) // *Point

Or the receiver argument is a variable of type T and the receiver parameter has type *T. The compiler implicitly takes the address of the variable:

p.ScaleBy(2) // implicit (&p)

Or the receiver argument has type *T and the receiver parameter has type T. The compiler implicitly dereferences the receiver, in other words, loads the value:

pptr.Distance(q) // implicit (*pptr)

If all the methods of a named type T have a receiver type of T itself (not *T), it is safe to copy instances of that type; calling any of its methods necessarily makes a copy.

 

The type of an anonymous field may be a pointer to a named type, in which case fields and methods are promoted indirectly from the pointed-to object. Adding another level of indirection lets us share common structures and vary the relationships between objects dynamically.

 

Usually we select and call a method in the same expression, as in p.Distance(), but it’s possible to separate these two operations. The selector p.Distance yields a method value, a function that binds a method (Point.Distance) to a specific receiver value p. This function can then be invoked without a receiver value; it needs only the non-receiver arguments.

Related to the method value is the method expression. When calling a method, as opposed to an ordinary function, we must supply the receiver in a special way using the selector syntax. A method expression, written T.f or (*T).f where T is a type, yields a function value with a regular first parameter taking the place of the receiver, so it can be called in the usual way.

 

A variable or method of an object is said to be encapsulated if it is inaccessible to clients of the object. Encapsulation, sometimes called information hiding, is a key aspect of object-oriented programming.

Go has only one mechanism to control the visibility of names: capitalized identifiers are exported from the package in which they are defined, and uncapitalized names are not. The same mechanism that limits access to members of a package also limits access to the fields of a struct or the methods of a type. As a consequence, to encapsulate an object, we must make it a struct.

Another consequence of this name-based mechanism is that the unit of encapsulation is the package, not the type as in many other languages. The fields of a struct type are visible to all code within the same package. Whether the code appears in a function or a method makes no difference.

Encapsulation provides three benefits. First, because clients cannot directly modify the object’s variables, one need inspect fewer statements to understand the possible values of those variables.

Second, hiding implementation details prevents clients from depending on things that might change, which gives the designer greater freedom to evolve the implementation without breaking API compatibility.

The third benefit of encapsulation, and in many cases the most important, is that it prevents clients from setting an object’s variables arbitrarily. Because the object’s variables can be set only by functions in the same package, the author of that package can ensure that all those functions maintain the object’s internal invariants.