Go语言的数据类型

以下摘自The Go Programming Language

Go’s types fall into four categories: basic types, aggregate types, reference types, and interface types. Basic types, include numbers, strings, and booleans. Aggregate types—arrays and structs —form more complicated data types by combining values of several simpler ones. Reference types are a diverse group that includes pointers, slices, maps, functions, and channels, but what they have in common is that they all refer to program variables or state indirectly, so that the effect of an operation applied to one reference is observed by all copies of that reference.

 

Go语言中变量的scope

以下摘自The Go Programming Language

A syntactic block is a sequence of statements enclosed in braces like those that surround the body of a function or loop. A name declared inside a syntactic block is not visible outside that block. The block encloses its declarations and determines their scope. We can generalize this notion of blocks to include other groupings of declarations that are not explicitly surrounded by braces in the source code; we’ll call them all lexical blocks. There is a lexical block for the entire source code, called the universe block; for each package; for each file; for each for, if, and switch statement; for each case in a switch or select statement; and, of course, for each explicit syntactic block.

A declaration’s lexical block determines its scope, which may be large or small. The declarations of built-in types, functions, and constants like int, len, and true are in the universe block and can be referred to throughout the entire program. Declarations outside any function, that is, at package level, can be referred to from any file in the same package. Imported packages, are declared at the file level, so they can be referred to from the same file, but not from another file in the same package without another import. Many declarations, like that of the variables in the function, are local, so they can be referred to only from within the same function or perhaps just a part of it.

The scope of a control-flow label, as used by break, continue, and goto statements, is the entire enclosing function.

需要注意universe block的定义:Go语言的built-in类型,函数和常量的scope都属于universe block

Go语言中的byte和rune

Go语言中byterune实质上就是uint8int32类型。byte用来强调数据是raw data,而不是数字;而rune用来表示Unicodecode point参考规范

uint8       the set of all unsigned  8-bit integers (0 to 255)
int32       the set of all signed 32-bit integers (-2147483648 to 2147483647)

byte        alias for uint8
rune        alias for int32

可以通过下面程序验证:

package main

import "fmt"

func byteSlice(b []byte) []byte {
    return b
}

func runeSlice(r []rune) []rune {
    return r
}

func main() {
    b := []byte{0, 1}
    u8 := []uint8{2, 3}
    fmt.Printf("%T %T \n", b, u8)
    fmt.Println(byteSlice(b))
    fmt.Println(byteSlice(u8))

    r := []rune{4, 5}
    i32 := []int32{6, 7}
    fmt.Printf("%T %T \n", r, i32)
    fmt.Println(runeSlice(r))
    fmt.Println(runeSlice(i32))
}

执行结果如下:

[]uint8 []uint8
[0 1]
[2 3]
[]int32 []int32
[4 5]
[6 7]

参考资料:
Difference between []uint8 && []byte (Golang Slices)

 

Oracle笔记(10)——redo日志文件

以下摘自Oracle log files : An introduction

Online redo Oracle log files are filled with redo records. A redo record, also called a redo entry, is made up of a group of change vectors, each of which is a description of a change made to a single block in the database.

Redo日志文件由redo record组成,每个redo record(又称作redo entry)又由一组change vector构成。

The online redo log file that Log Writer (LGWR) is actively writing to is called the current online redo log file. Online redo Oracle log files that are required for instance recovery are called active online redo log files. Online redo log files that are not required for instance recovery are called inactive.

参考下面例子:

SQL> select group#,members,bytes/1024/1024,status from v$log;

    GROUP#    MEMBERS BYTES/1024/1024 STATUS
---------- ---------- --------------- ----------------
         1          1             100 INACTIVE
         2          1             100 ACTIVE
         3          1             100 INACTIVE
         4          1             300 CURRENT

CURRENTLGWR进程正在写入的文件;ACTIVE是用于recovery的;INACTIVE则不是。

 

Oracle笔记(9)——checkpoint和CKPT进程

以下摘自Oracle 12c For Dummies

The checkpoint process(CKPT) is responsible for initiating check points. A check point is when the system periodically dumps all the dirty buffers to disk. Most commonly, this occurs when the database receives a shutdown command. It also updates the data file headers and the control files with the check point information so the SMON know where to start recovery in the event of a system crash.

CKPT进程是初始化checkpoint,而checkpoint的作用是让系统可以周期性地把“脏数据”更新到磁盘。

 

getopt和getopt_long

这篇笔记选自Using getopt。 一个典型的的Unix程序格式如下:

getopt [-dmp] [-s name] -f name file [file ...]

a)dmp是可选option,在一个[]中表示它们可以一起使用;

b)[-s name]表示s是一个带参数的可选option
c)-f name表示f是一个带参数的必选option
d)file [file ...]表示程序还需要一个或多个命令行参数。
getopt函数原型如下:

#include <unistd.h>

int getopt(int argc, char * const argv[], const char *optstring);

extern char *optarg;
extern int optind, opterr, optopt;

需要注意以下几点:

a)每次调用getopt后,如果option带参数,optarg指向后面跟着的参数;optind则表示下一次处理optionindex。因此当getopt解析完所有option后,如果同argc相同,则表示没有命令行参数。
b)getopt前两个参数直接从main函数参数得到,第三个参数指定如何处理option"df:mps:"。冒号表示前面的option后面需要带参数。如果getopt解析option时遇到不在optstring中的option返回?,把option全部解析完返回-1
下面看一下getopt_longgetopt_long_only(参考getopt(3) – Linux man page):

#include <getopt.h>

int getopt_long(int argc, char * const argv[],
           const char *optstring,
           const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char * const argv[],
        const char *optstring,
        const struct option *longopts, int *longindex);

getopt_long除了可以处理short option外,还可以处理long option(以--开头)。关于struct option定义如下:

struct option {
    const char *name;
    int         has_arg;
    int        *flag;
    int         val;
};
The meanings of the different fields are:
name
is the name of the long option.

has_arg
is: no_argument (or 0) if the option does not take an argument; required_argument (or 1) if the option requires an argument; or optional_argument (or 2) if the option takes an optional argument.  

flag
specifies how results are returned for a long option. If flag is NULL, then getopt_long() returns val. (For example, the calling program may set val to the equivalent short option character.) Otherwise, getopt_long() returns 0, and flag points to a variable which is set to val if the option is found, but left unchanged if the option is not found.

val
is the value to return, or to load into the variable pointed to by flag.

如果flagNULLgetopt_long会返回val的值,因此通常会把flag置成NULL,把val置成与long option对应的short option。否则getopt_long会返回0,并把val的值赋给flag

参考下列代码(选自GNU binutils中的size命令)可以更好地了解getopt_long

#define OPTION_FORMAT (200)
#define OPTION_RADIX (OPTION_FORMAT + 1)
#define OPTION_TARGET (OPTION_RADIX + 1)

static struct option long_options[] =
{
  {"common", no_argument, &show_common, 1},
  {"format", required_argument, 0, OPTION_FORMAT},
  {"radix", required_argument, 0, OPTION_RADIX},
  {"target", required_argument, 0, OPTION_TARGET},
  {"totals", no_argument, &show_totals, 1},
  {"version", no_argument, &show_version, 1},
  {"help", no_argument, &show_help, 1},
  {0, no_argument, 0, 0}
};


 while ((c = getopt_long (argc, argv, "ABHhVvdfotx", long_options,
               (int *) 0)) != EOF)
    switch (c)
      {
      case OPTION_FORMAT:
    switch (*optarg)
      {
      case 'B':
      case 'b':
        berkeley_format = 1;
        break;
      case 'S':
      case 's':
        berkeley_format = 0;
        break;
      default:
        non_fatal (_("invalid argument to --format: %s"), optarg);
        usage (stderr, 1);
      }
    break;

    ......

    case 0:
    break;
    ......
    }

{"format", required_argument, 0, OPTION_FORMAT}flagNULL,所以getopt_long返回值是OPTION_FORMAT;根据optarg确定应该使用哪种format。而{"totals", no_argument, &show_totals, 1}flagNULLgetopt_long返回值是0show_totals的值为1

getopt_longgetopt_long_only的区别:

getoptlongonly() is like getopt_long(), but ‘-‘ as well as “–” can indicate a long option. If an option that starts with ‘-‘ (not “–“) doesn’t match a long option, but does match a short option, it is parsed as a short option instead.

 

Oracle笔记(8)——latch

LatchOracle串行的并发访问内存的机制,也可以把latch看成是lock。当一个进程获取一个latch时,它或者成功或者失败。但是失败后,进程不会释放CPU,而是会继续尝试获取latch(具体行为取决于mode)。

参考资料:
Latches and Latch Contention
Latch and Mutex ContentionTroubleshooting in Oracle

 

/etc/hosts文件

/etc/hosts文件保存IP地址和hostname之间的映射。格式是:IP地址 canocial_hostname name。举例如下:

127.0.0.1       localhost
192.168.1.10    foo.mydomain.org       foo
192.168.1.13    bar.mydomain.org       bar
146.82.138.7    master.debian.org      master
209.237.226.90  www.opensource.org

尽管现在host table已经被DNS取代了,但是有时在bootstrappingNIS和隔离节点的环境下仍然会用到/etc/hosts
修改/etc/hosts文件可以马上生效,但有时需要清空程序的缓存。

参考资料:
hosts

 

Profiling CPU使用

本文内容取自于《Systems Performance: Enterprise and the Cloud》

Profiling CPU的方法是通过对CPU状态进行周期性地采样,然后进行分析。包含5个步骤:

1. Select the type of profile data to capture, and the rate.
2. Begin sampling at a timed interval.
3. Wait while the activity of interest occurs.
4. End sampling and collect sample data.
5. Process the data.

CPU采样数据基于下面两个因素:

a. User level, kernel level, or both
b. Function and offset (program-counter-based), function only, partial stack trace, or full stack trace

抓取user levelkernel level所有的函数调用栈固然可以完整地得到CPUprofile,但这样会产生太多的数据。因此通常只采样user levelkernel level部分函数调用栈就可以了,有时可能仅需要保留函数的名字。

下面是一个使用DTraceCPU采样的例子:

 # dtrace -qn 'profile-997 /arg1/ {@[execname, ufunc(arg1)] = count();} tick-10s{exit(0)}'

 top                                                 libc.so.7`0x801154fec                                             1
 top                                                 libc.so.7`0x8011e5f28                                             1
 top                                                 libc.so.7`0x8011f18a9                                             1

 

Go语言的类型转换

以下摘自The Go Programming Language

For every type T, there is a corresponding conversion operation T(x) that converts the value x to type T. A conversion from one type to another is allowed if both have the same underlying type, or if both are unnamed pointer types that point to variables of the same underlying type; these conversions change the type but not the representation of the value. If x is assignable to T, a conversion is permitted but is usually redundant.

Conversions are also allowed between numeric types, and between string and some slice types. These conversions may change the representation of the value. For instance, converting a floating-point number to an integer discards any fractional part, and converting a string to a []byte slice allocates a copy of the string data. In any case, a conversion never fails at run time.