参考https://studygolang.com/pkgdoc

导入形式:

import "time"

time包提供了时间的显示和测量用的函数。日历的计算采用的是公历。

1》时间点Time

type Time

type Time struct {wall uint64ext  int64loc *Location
}

Time代表一个纳秒精度的时间点。

Time零值代表时间点January 1, year 1, 00:00:00.000000000 UTC。因为本时间点一般不会出现在使用中,IsZero方法提供了检验时间是否显式初始化的一个简单途径。

每一个时间都具有一个地点信息(及对应地点的时区信息),当计算时间的表示格式时,如Format、Hour和Year等方法,都会考虑该信息。Local、UTC和In方法返回一个指定时区(但指向同一时间点)的Time。修改地点/时区信息只是会改变其表示;不会修改被表示的时间点,因此也不会影响其计算。

func (Time) String

func (t Time) String() string

String返回采用如下格式字符串的格式化时间。

"2006-01-02 15:04:05.999999999 -0700 MST"

const (ANSIC       = "Mon Jan _2 15:04:05 2006"UnixDate    = "Mon Jan _2 15:04:05 MST 2006"RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"RFC822      = "02 Jan 06 15:04 MST"RFC822Z     = "02 Jan 06 15:04 -0700" // 使用数字表示时区的RFC822RFC850      = "Monday, 02-Jan-06 15:04:05 MST"RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // 使用数字表示时区的RFC1123RFC3339     = "2006-01-02T15:04:05Z07:00"RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"Kitchen     = "3:04PM"// 方便的时间戳Stamp      = "Jan _2 15:04:05"StampMilli = "Jan _2 15:04:05.000"StampMicro = "Jan _2 15:04:05.000000"StampNano  = "Jan _2 15:04:05.000000000"
)

这些预定义的版式用于time.Format和time.Parse函数。用在版式中的参考时间是:

Mon Jan 2 15:04:05 MST 2006

对应的Unix时间是1136239445

1)举例如何使用在time.Format函数中:

func Now

func Now() Time

Now返回当前本地时间。

func (Time) Format

func (t Time) Format(layout string) string

Format根据layout指定的格式返回t代表的时间点的格式化文本表示,即将时间转换成想要的格式,layout定义了参考时间

package main
import("fmt""time"
)func main() {fmt.Println(time.Now().Format(time.UnixDate))         //Tue Feb 12 12:10:21 CST 2019fmt.Println(time.Now().Format(time.RFC3339Nano))      //2019-02-12T12:10:21.880328+08:00fmt.Println(time.Now().Format(time.StampMicro))       //Feb 12 12:10:21.880337//自定义格式fmt.Println(time.Now().Format("2006-01-02 15:04:05")) //2019-02-12 12:10:21fmt.Println(time.Now().Format("Jan 2, 2006 at 3:04pm (MST)"))  //Feb 12, 2019 at 12:10pm (CST)fmt.Println(time.Now().Format("2006-Jan-02"))  //2019-Feb-12
}

2)如何使用在time.Parse函数中,上面例子的逆向:

func Parse

func Parse(layout, value string) (Time, error)

Parse解析一个格式化的时间字符串并返回它代表的时间。layout定义了参考的时间格式

package main
import("fmt""time"
)func main() {unix, _ := time.Parse(time.UnixDate, "Tue Feb 12 12:10:21 CST 2019")fmt.Println(unix) //2019-02-12 12:10:21 +0800 CST
rfc, _ := time.Parse(time.RFC3339Nano, "2019-02-12T12:10:21.880328+08:00")fmt.Println(rfc) //2019-02-12 12:10:21.880328 +0800 CST
stamp, _ := time.Parse(time.StampMicro, "Feb 12 12:10:21.880337")fmt.Println(stamp) //0000-02-12 12:10:21.880337 +0000 UTC
custom1Form := "2006-01-02 15:04:05"custom1, _ := time.Parse(custom1Form, "2019-02-12 12:10:21")fmt.Println(custom1) //2019-02-12 12:10:21 +0000 UTC
custom2Form := "Jan 2, 2006 at 3:04pm (MST)"custom2, _ := time.Parse(custom2Form, "Feb 12, 2019 at 12:10pm (CST)")fmt.Println(custom2) //2019-02-12 12:10:00 +0800 CST
custom3Form := "2006-Jan-02"custom3, _ := time.Parse(custom3Form, "2019-Feb-12")fmt.Println(custom3) //2019-02-12 00:00:00 +0000 UTC
}

数字表示的时区格式如下:

-0700  ±hhmm
-07:00 ±hh:mm

将格式字符串中的负号替换为Z会触发ISO 8601行为(当时区是UTC时,输出Z而不是时区偏移量),这样:

Z0700  Z or ±hhmm
Z07:00 Z or ±hh:mm

其他的获取Time对象的方法:

首先先说明时区Location

type Location

type Location struct {name stringzone []zonetx   []zoneTranscacheStart int64cacheEnd   int64cacheZone  *zone
}

Location代表一个(关联到某个时间点的)地点,以及该地点所在的时区。

var Local *Location = &localLoc

Local代表系统本地,对应本地时区,通过time.Local来使用。

var UTC *Location = &utcLoc

UTC代表通用协调时间,对应零时区,通过time.UTC来使用。

3)

func LoadLocation

func LoadLocation(name string) (*Location, error)

LoadLocation返回使用给定的名字创建的Location,即时区。

如果name是""或"UTC",返回UTC;如果name是"Local",返回Local;否则name应该是IANA时区数据库里有记录的地点名(该数据库记录了地点和对应的时区),如"America/New_York"。

LoadLocation函数需要的时区数据库可能不是所有系统都提供,特别是非Unix系统。此时LoadLocation会查找环境变量ZONEINFO指定目录或解压该变量指定的zip文件(如果有该环境变量);然后查找Unix系统的惯例时区数据安装位置,最后查找$GOROOT/lib/time/zoneinfo.zip。

func (Time) In

func (t Time) In(loc *Location) Time

In返回采用loc指定的地点和时区,但指向同一时间点的Time。如果loc为nil会panic。

package main
import("fmt""time"
)func main() {loc, _ := time.LoadLocation("America/Los_Angeles") //美国洛杉矶时区PSTfmt.Println(loc) //America/Los_Angelesfmt.Println(time.Now()) //2019-02-12 15:03:12.649876 +0800 CST m=+0.000715568,相对于UTC时区正向差8小时fmt.Println(time.Now().In(loc)) //2019-02-11 23:03:12.649952 -0800 PST,相对于UTC时区正向差8小时,因此loc时区和本地时区相差16小时
}

4)

func ParseInLocation

func ParseInLocation(layout, value string, loc *Location) (Time, error)

ParseInLocation类似Parse但有两个重要的不同之处。第一,当缺少时区信息时,Parse将时间解释为UTC时间,而ParseInLocation将返回值的Location设置为loc;第二,当时间字符串提供了时区偏移量信息时,Parse会尝试去匹配本地时区,而ParseInLocation会去匹配loc。

举例:

package main
import("fmt""time"
)func main() {loc, _ := time.LoadLocation("America/Los_Angeles")custom2Form := "2006-01-02 15:04:05"custom2, _ := time.ParseInLocation(custom2Form, "2019-02-12 12:10:21", loc)fmt.Println(custom2) //2019-02-12 12:10:21 -0800 PST,可见将时区设置为了指定的loc时区custom2Parse, _ := time.Parse(custom2Form, "2019-02-12 12:10:21")fmt.Println(custom2Parse) //2019-02-12 12:10:21 +0000 UTC,可见如果没有设置时区则默认为UTC时区
}

5)

func Unix

func Unix(sec int64, nsec int64) Time

Unix创建一个本地时间,对应sec和nsec表示的Unix时间(从January 1, 1970 UTC至该时间的秒数和纳秒数)。

nsec的值在[0, 999999999]范围外是合法的。

获得时间的时间戳

func (Time) Unix

func (t Time) Unix() int64

Unix将t表示为Unix时间,即从时间点January 1, 1970 UTC到时间点t所经过的时间(单位秒)。

func (Time) UnixNano

func (t Time) UnixNano() int64

UnixNano将t表示为Unix时间,即从时间点January 1, 1970 UTC到时间点t所经过的时间(单位纳秒)。如果纳秒为单位的unix时间超出了int64能表示的范围,结果是未定义的。注意这就意味着Time零值调用UnixNano方法的话,结果是未定义的。

举例:

package main
import("fmt""time"
)func main() {fmt.Println(time.Now().Unix())     //1549956211fmt.Println(time.Now().UnixNano()) //1549956211529784000   fmt.Println(time.Unix(1549956211, 529784000)) //2019-02-12 15:23:31.529784 +0800 CST
}

然后使用上面例子得到的秒数或纳秒数来调用Unix得到Time对象:

package main
import("fmt""time"
)func main() {fmt.Println(time.Unix(1549956211, 0)) //2019-02-12 15:23:31 +0800 CSTfmt.Println(time.Unix(0, 1549956211529784000)) //2019-02-12 15:23:31.529784 +0800 CST
}

6)

func Date

func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time

Date返回一个时区为loc、当地时间为:

year-month-day hour:min:sec + nsec nanoseconds

的时间点。

month、day、hour、min、sec和nsec的值可能会超出它们的正常范围,在转换前函数会自动将之规范化。如October 32被修正为November 1。

举例:

package main
import("fmt""time"
)func main() {fmt.Println(time.Unix(1549956211, 529784000)) //2019-02-12 15:23:31.529784 +0800 CST//等价于上面的Unix方法t := time.Date(2019, time.February, 12, 15, 23, 31, 529784000, time.Local)fmt.Println(t)////2019-02-12 15:23:31.529784 +0800 CST
}

当你得到了Time对象后,你就能够调用相应的函数来获得相应的信息,选择其中几个说明,其他省略:

func (Time) Round

func (t Time) Round(d Duration) Time

返回距离t最近的时间点,得到的是晚于t的时间,该时间点应该满足从Time零值到该时间点的时间段能整除d;如果有两个满足要求的时间点,距离t相同,会向上舍入;如果d <= 0,会返回t的拷贝。

举例:

package main
import("fmt""time"
)func main() {t := time.Date(2019, time.February, 12, 15, 23, 31, 529784000, time.Local)fmt.Println(t)////2019-02-12 15:23:31.529784 +0800 CST
round := []time.Duration{time.Nanosecond,  //按纳秒四舍五入,9位time.Microsecond, //按微秒,6位time.Millisecond, //按毫秒,3位,0省略time.Second,      //按秒2 * time.Second,  //按2秒time.Minute,      //按分10 * time.Minute, //按10分time.Hour,        //按小时
    }for _, d := range round {fmt.Printf("t.Round(%6s) = %s\n", d, t.Round(d).Format("15:04:05.999999999"))}
}

返回:

userdeMBP:go-learning user$ go run test.go
2019-02-12 15:23:31.529784 +0800 CST
t.Round(   1ns) = 15:23:31.529784
t.Round(   1µs) = 15:23:31.529784
t.Round(   1ms) = 15:23:31.53 //四舍五入为530
t.Round(    1s) = 15:23:32 //四舍五入为32
t.Round(    2s) = 15:23:32
t.Round(  1m0s) = 15:24:00
t.Round( 10m0s) = 15:20:00
t.Round(1h0m0s) = 15:00:00

func (Time) Truncate

func (t Time) Truncate(d Duration) Time

类似Round,但是返回的是最接近但早于t的时间点;如果d <= 0,会返回t的拷贝。

可见同样的值使用Truncate得到的结果和Round是不同的

举例:

package main
import("fmt""time"
)func main() {t := time.Date(2019, time.February, 12, 15, 23, 31, 529784000, time.Local)fmt.Println(t)////2019-02-12 15:23:31.529784 +0800 CST
round := []time.Duration{time.Nanosecond,  //按纳秒四舍五入,9位time.Microsecond, //按微秒,6位time.Millisecond, //按毫秒,3位,0省略time.Second,      //按秒2 * time.Second,  //按2秒time.Minute,      //按分10 * time.Minute, //按10分time.Hour,        //按小时
    }for _, d := range round {fmt.Printf("t.Round(%6s) = %s\n", d, t.Truncate(d).Format("15:04:05.999999999"))}
}

返回:

userdeMBP:go-learning user$ go run test.go
2019-02-12 15:23:31.529784 +0800 CST
t.Round(   1ns) = 15:23:31.529784
t.Round(   1µs) = 15:23:31.529784
t.Round(   1ms) = 15:23:31.529
t.Round(    1s) = 15:23:31
t.Round(    2s) = 15:23:30
t.Round(  1m0s) = 15:23:00
t.Round( 10m0s) = 15:20:00
t.Round(1h0m0s) = 15:00:00

有关Duration的内容向下看

2》

type Weekday

type Weekday int

Weekday代表一周的某一天。

const (Sunday Weekday = iotaMondayTuesdayWednesdayThursdayFridaySaturday
)

func (Weekday) String

func (d Weekday) String() string

String返回该日(周几)的英文名("Sunday"、"Monday",……)

func (Time) Weekday

func (t Time) Weekday() Weekday

返回时间点t对应的那一周的周几。

type Month

type Month int

Month代表一年的某个月。

const (January Month = 1 + iotaFebruaryMarchAprilMayJuneJulyAugustSeptemberOctoberNovemberDecember
)

func (Month) String

func (m Month) String() string

String返回月份的英文名("January","February",……)

举例:

package main
import("fmt""time"
)func main() {fmt.Println(time.Now().Weekday()) //默认调用func (Weekday) String()函数,返回Tuesdayfmt.Println(time.Now().Month()) //默认调用func (Month) String()函数,返回February
}

3》时间段Duration

type Duration

type Duration int64

Duration类型代表两个时间点之间经过的时间,以纳秒为单位。可表示的最长时间段大约290年。

const (Nanosecond  Duration = 1Microsecond          = 1000 * NanosecondMillisecond          = 1000 * MicrosecondSecond               = 1000 * MillisecondMinute               = 60 * SecondHour                 = 60 * Minute
)

常用的时间段。没有定义一天或超过一天的单元,以避免夏时制的时区切换的混乱。

要将Duration类型值表示为某时间单元的个数,用除法:

second := time.Second
fmt.Print(int64(second/time.Millisecond)) // prints 1000

要将整数个某时间单元表示为Duration类型值,用乘法:

seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s

func ParseDuration

func ParseDuration(s string) (Duration, error)

ParseDuration解析一个时间段字符串。一个时间段字符串是一个序列,每个片段包含可选的正负号、十进制数、可选的小数部分和单位后缀,如"300ms"、"-1.5h"、"2h45m"。合法的单位有"ns"、"us" /"µs"、"ms"、"s"、"m"、"h"。

举例:

package main
import("fmt""time"
)func main() {dur1, _ := time.ParseDuration("1.5s")//1.5sdur2, _ := time.ParseDuration("2h45m") //2h45m0sdur3, _ := time.ParseDuration("-1.5h") //-1h30m0s
    fmt.Println(dur1)fmt.Println(dur2)fmt.Println(dur3)
}

func Since

func Since(t Time) Duration

Since返回从t到现在经过的时间,等价于time.Now().Sub(t)。

举例:

package main
import("fmt""time"
)func main() {t := time.Date(2019, time.February, 12, 15, 23, 31, 529784000, time.Local)fmt.Println(t)//2019-02-12 15:23:31.529784 +0800 CSTfmt.Println(time.Since(t))//50m31.878043s,现在据上面的时间已经过了50分钟31秒
}

func (Duration) String

func (d Duration) String() string

返回时间段采用"72h3m0.5s"格式的字符串表示。最前面可以有符号,数字+单位为一个单元,开始部分的0值单元会被省略;如果时间段<1s,会使用"ms"、"us"、"ns"来保证第一个单元的数字不是0;如果时间段为0,会返回"0"。

4》用于时间运算

来自https://blog.csdn.net/wschq/article/details/80114036

      // func Sleep(d Duration)   休眠多少时间,休眠时处于阻塞状态,后续程序无法执行time.Sleep(time.Duration(10) * time.Second)// func After(d Duration) <-chan Time  非阻塞,可用于延迟time.After(time.Duration(10) * time.Second)//select { case m := <-c: handle(m) case <-time.After(5 * time.Minute): fmt.Println("timed out") }// func Since(t Time) Duration 两个时间点的间隔start := time.Now()fmt.Println(time.Since(start))   // 等价于 Now().Sub(t), 可用来计算一段业务的消耗时间
func Until(t Time) Duration     //  等价于 t.Sub(Now()),t与当前时间的间隔// func (t Time) Add(d Duration) Timefmt.Println(dt.Add(time.Duration(10) * time.Second))   // 加
func (t Time) Sub(u Time) Duration                    // 减 // func (t Time) AddDate(years int, months int, days int) Timefmt.Println(dt.AddDate(1, 1, 1))// func (t Time) Before(u Time) bool// func (t Time) After(u Time) bool// func (t Time) Equal(u Time) bool          比较时间点时尽量使用Equal函数 

5》定点计时

计时器(Timer)的原理和倒计时闹钟类似,都是给定多少时间后触发。

打点器(Ticker)的原理和钟表类似,钟表每到整点就会触发。

这两种方法创建后会返回 time.Ticker 对象和 time.Timer 对象,里面通过一个 C 成员,类型是只能接收的时间通道(<-chan Time),使用这个通道就可以获得时间触发的通知。

1)type Timer

type Timer struct {C <-chan Time// 内含隐藏或非导出字段
}

Timer类型代表单次时间事件。当Timer到期时,当时的时间会被发送给C,除非Timer是被AfterFunc函数创建的。

创建Timer的两种方法:

1.func NewTimer

func NewTimer(d Duration) *Timer

NewTimer创建一个Timer,它会在最少过去时间段d后到期,向其自身的C字段发送当时的时间。

2.func AfterFunc

func AfterFunc(d Duration, f func()) *Timer

AfterFunc另起一个go程等待时间段d过去,然后调用f。它返回一个Timer,可以通过调用其Stop方法来取消等待和对f的调用。

使用time.AfterFunc()实现等待一段时间后调用函数,并直到该函数生成的另一goroutine结束后才结束main()函数的goroutine

package main
import("fmt""time" ) func main() { //声明一个用于退出的通道 exit := make(chan int) fmt.Println("start") //过1秒后,就会开一个新goroutine来运行匿名函数  time.AfterFunc(time.Second, func(){ //该匿名函数的作用就是在1秒后打印结果,并通知main()函数可以结束主goroutine fmt.Println("one second after") exit <- 0 }) //main()正在等待从exit通道中接受数据来结束主goroutine <- exit }

返回:

userdeMBP:go-learning user$ go run test.go
start
one second after

⚠️以上两函数都可以使用 Reset:

func (*Timer) Reset

func (t *Timer) Reset(d Duration) bool

Reset使t重新开始计时,(本方法返回后再)等待时间段d过去后到期。如果调用时t还在等待中会返回真;如果t已经到期或者被停止了会返回假。

这个有个需要注意的地方是使用 Reset 时需要确保 t.C 通道被释放时才能调用,以防止发生资源竞争的问题,可通过以下方式解决:

      if !t.Stop() {//如果t已经被停止或者过期了,则先将t.C 通道释放,然后才调用Reset来重新计时,否则此时通道是满的,导致资源竞争<-t.C}t.Reset(d)

func (*Timer) Stop

func (t *Timer) Stop() bool

Stop停止Timer的执行。如果还没停止并停止了t会返回真;如果t已经被停止或者过期了会返回假。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。

2)type Ticker

type Ticker struct {C <-chan Time // 周期性传递时间信息的通道// 内含隐藏或非导出字段
}

Ticker保管一个通道,并每隔一段时间向其传递"tick"。

func NewTicker

func NewTicker(d Duration) *Ticker

NewTicker返回一个新的Ticker,该Ticker包含一个通道字段,并会每隔时间段d就向该通道发送当时的时间。它会调整时间间隔或者丢弃tick信息以适应反应慢的接收者。如果d<=0会panic。关闭该Ticker可以释放相关资源。

举例:

下面代码创建一个打点器Ticker,每 500 毫秒触发一起;创建一个计时器Timer,2 秒后触发,只触发一次。

package main
import("fmt""time" ) func main() { //创建一个打点器,每500毫秒触发一次 ticker := time.NewTicker(time.Millisecond * 500) //创建一个计时器,2秒后触发 timer := time.NewTimer(time.Second * 2) //声明计数变量 var count int //不断检查通道情况 for{ //多路复用通道 select{ case <- timer.C://计时器到时了,即2秒已到 fmt.Println("time is over,stop!!") goto StopLoop case <- ticker.C://打点器触发了,说明已隔500毫秒 count++ fmt.Println("tick : ", count) } } //停止循环所到的标签  StopLoop: fmt.Println("ending") } 

返回:

userdeMBP:go-learning user$ go run test.go
tick :  1
tick :  2
tick :  3 tick : 4 time is over,stop!! ending

func (*Ticker) Stop

func (t *Ticker) Stop()

Stop关闭一个Ticker。在关闭后,将不会发送更多的tick信息。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。

转载于:https://www.cnblogs.com/wanghui-garcia/p/10341865.html

go标准库的学习-time相关推荐

  1. go标准库的学习-crypto/sha1

    参考:https://studygolang.com/pkgdoc 导入方式: import "crypto/sha1" sha1包实现了SHA1哈希算法,参见RFC 3174. ...

  2. 《C++标准库》学习笔记 — STL —流

    <C++标准库>学习笔记 - STL -流 一.操控器 1.原理 2.自定义操控器 3.控制输入的宽度 二.自定义 I/O 操作符 1.重载输出操作符 2.输入操作符 三.自定义格式化标志 ...

  3. C++“准”标准库Boost学习指南(1):智能指针Boost.smart_ptr

    我们学习C++都知道智能指针,例如STL中的std::auto_ptr,但是为什么要使用智能指针,使用它能带给我们什么好处呢? 最简单的使用智能指针可以不会因为忘记delete指针而造成内存泄露.还有 ...

  4. python标准库之socket_python标准库SocketServer学习

    导语:大牛们常常说阅读源码是很低效的学习方法.但对我辈初学者而言,阅读源码却是掌握编程思想.编码规范的好途径.简而言之,读源码不是万能的,不读源码是万万不能的. SocketServer是标准库中一个 ...

  5. c++标准库--cstdio学习

    cstdio学习 宏 类型 函数 printf() scanf 输出 源代码 宏 EOF :表示已到达文件结尾或发出其他一些故障情况 NULL:表示空指针 类型 FILE:包含控制流的信息的对象 函数 ...

  6. go标准库的学习-crypto/aes

    参考:https://studygolang.com/pkgdoc 导入方式: import "crypto/aes" aes包实现了AES加密算法,参见U.S. Federal ...

  7. go标准库的学习-sync互斥

    https://studygolang.com/pkgdoc 导入方法: import "sync" sync包提供了基本的同步基元,如互斥锁.除了Once和WaitGroup类型 ...

  8. go标准库的学习-fmt

    参考https://studygolang.com/pkgdoc 导入方式: import "fmt" mt包实现了类似C语言printf和scanf的格式化I/O.格式化动作(' ...

  9. go标准库的学习-errors

    参考https://studygolang.com/pkgdoc 导入方式: import "errors" errors包实现了创建错误值的函数. 1)func New func ...

最新文章

  1. SSH 组建轻量级架构 附录 -- 遇到的问题和解答
  2. 开发日记-20190423 关键词 android静态代理类代理方法打断点debug 退出当前activity 闪退
  3. 怎样修改当前分支最新一次提交的message信息?
  4. 分析一个文本文件(英文文章)中各个词出现的频率,并且把频率最高的十个词打印出来...
  5. nginx linux详细安装部署教程,Nginx Linux详细安装及部署实战
  6. 玩转计划任务命令:schtasks
  7. SQL Server常用查询指令
  8. 计算机网络图标显示不出来,网络连接图标不见了的原因和解决方法【详细介绍】...
  9. RoadRunner安装与使用教程
  10. 移远EC20串口使用阻塞问题
  11. xv6实验课程--系统调用
  12. 分治法--线性时间选择
  13. VNCTF2021[WEB]
  14. java渗透_java 渗透模型
  15. PHP WEB程序设计信息表,WEB程序设计(PHP)2020知到答案全套
  16. 算法leetcode|剑指 Offer 27. 二叉树的镜像|226. 翻转二叉树(rust很强)
  17. OS X平台的Dylib劫持技术(下)
  18. 计算机二级知识点——栈
  19. 携手聚力 共赢数智未来丨物通博联招募生态合作伙伴
  20. 一种新型免费无损图片格式FLIF

热门文章

  1. 多行文本框拖动问题解决
  2. 【莓控】黑莓8110中文说明书
  3. mysql之select查询
  4. 四. RxJava之基本原理
  5. eclipse team 没有svn
  6. [从0到1编写服务器]准备知识
  7. Android热修复升级探索——代码修复冷启动方案
  8. tomcat配置访问项目时不需要加项目名称
  9. jetty debug 启动 jettyconfig配置文件
  10. Exception in thread http-bio-80exec-1 java.lang.OutOfMemoryError: PermGen s解决方案