76. 归并排序

归并排序是典型的分治算法,它不断地将某个数组分为两个部分,分别对左子数组与右子数组进行排序,然后将两个数组合并为新的有序数组。

一般来说,小文件单机版排序比并发排序更快一些,但是大文件无法一次性读入内存处理,需要分块处理。单机版排序无法做到分布式排序,分布式排序需要联网进行,网络传输跟通道传输非常类似,稍作修改就可以做到在网络上进行排序。

并行和并发是有区别的,依赖操作系统和硬件是否支持。同时,在允许的情况下,使用有缓冲的通道和使用文件读写缓冲,有利于加快程序的处理速度,避免及时阻塞。

数组排序

对一个整数数组进行排序,系统库中已经提供了排序函数,直接使用即可。需要注意的是,Go中使用通道,使用不当会造成死锁。需要注意通道的使用,否则一运行就发生竞争条件造成程序无法执行而终止。

// 按升序排序
func InMemSort(in <-chan int) <-chan int {
    out := make(chan int, 4096)

    // 启动一个协程输出排序数据
    go func() {
        var a []int
        for v := range in {
            a = append(a, v)
        }
        fmt.Println("Read done: ", time.Now().Sub(startTime))

        sort.Ints(a)
        fmt.Println("Sort done: ", time.Now().Sub(startTime))

        // 将排序好的数据输出至通道中
        for _, n := range a {
            out <- n
        }

        close(out)
    }()

    return out
}

通常来说,协程的使用是成对出现的,并且习惯用Go匿名函数来操作。需要留意匿名函数的传参问题,可以去官方文档进行查看。go程运行时,函数调用是瞬间返回的。如果在其它地方使用range操作来处理通道,在通道数据发送完毕时必须显示关闭通道,否则必是死锁错误。

Read More

75. “你在森林,我在达达拉”

就像都市里大多数人一样,一辈子也不会认识,却一直生活在一起。 __《向左走向右走》

一、买票

按以往上班习惯,公司会提前告知春节放假通知。吃饭时听他们讲,百度只走法定节假日,但是你们可以根据自己的情况酌情调休。去年没回家,每次打电话,家里人都是问什么时候回家,就决定今年回家。看了下票的情况和休假安排,选择2月9号回家,连返程票一并买好。

Read More