MST

星途 面试题库

面试题:Go函数签名设计之高级难度题

假设你要实现一个通用的排序函数,该函数能对任何实现了特定接口类型的切片进行排序。请设计这个排序函数的签名,并说明如何通过接口约束来确保传入的切片类型是可排序的,同时要考虑函数签名如何适应不同类型的切片。
27.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 设计排序函数签名
    • 在Go语言中,可以这样设计:
    type Sortable interface {
        Len() int
        Less(i, j int) bool
        Swap(i, j int)
    }
    
    func Sort(data Sortable) {
        // 具体排序实现,例如使用冒泡排序
        n := data.Len()
        for i := 0; i < n - 1; i++ {
            for j := 0; j < n - i - 1; j++ {
                if data.Less(j + 1, j) {
                    data.Swap(j, j + 1)
                }
            }
        }
    }
    
  2. 通过接口约束确保切片类型可排序
    • 定义Sortable接口,该接口包含三个方法:
      • Len():返回切片的长度,这是排序算法需要知道的元素数量。
      • Less(i, j int) bool:比较切片中索引为ij的两个元素,返回true表示索引i的元素应该排在索引j的元素之前。
      • Swap(i, j int):交换切片中索引为ij的两个元素。
    • 任何需要排序的切片类型都必须实现这个Sortable接口。例如,对于一个整数切片:
    type IntSlice []int
    
    func (is IntSlice) Len() int {
        return len(is)
    }
    
    func (is IntSlice) Less(i, j int) bool {
        return is[i] < is[j]
    }
    
    func (is IntSlice) Swap(i, j int) {
        is[i], is[j] = is[j], is[i]
    }
    
    • 然后可以这样调用排序函数:
    func main() {
        ints := IntSlice{5, 4, 3, 2, 1}
        Sort(ints)
        fmt.Println(ints)
    }
    
  3. 函数签名适应不同类型切片
    • 由于Sort函数接受实现了Sortable接口的任何类型,所以只要为不同类型的切片实现Sortable接口,Sort函数就可以对其进行排序。例如,对于字符串切片也可以实现类似的接口方法:
    type StringSlice []string
    
    func (ss StringSlice) Len() int {
        return len(ss)
    }
    
    func (ss StringSlice) Less(i, j int) bool {
        return ss[i] < ss[j]
    }
    
    func (ss StringSlice) Swap(i, j int) {
        ss[i], ss[j] = ss[j], ss[i]
    }
    
    • 然后就可以对字符串切片进行排序:
    func main() {
        strings := StringSlice{"banana", "apple", "cherry"}
        Sort(strings)
        fmt.Println(strings)
    }
    

在其他语言如Java中,可以通过泛型和接口来实现类似功能:

  1. 定义接口
    public interface Sortable<T> {
        int compare(T a, T b);
    }
    
  2. 定义排序函数
    import java.util.Arrays;
    
    public class Sorter {
        public static <T> void sort(T[] array, Sortable<T> sorter) {
            Arrays.sort(array, (a, b) -> sorter.compare(a, b));
        }
    }
    
  3. 为具体类型实现接口
    public class IntegerSorter implements Sortable<Integer> {
        @Override
        public int compare(Integer a, Integer b) {
            return a - b;
        }
    }
    
  4. 调用排序函数
    public class Main {
        public static void main(String[] args) {
            Integer[] numbers = {5, 4, 3, 2, 1};
            Sorter.sort(numbers, new IntegerSorter());
            for (int num : numbers) {
                System.out.print(num + " ");
            }
        }
    }
    

这样,通过接口和泛型,函数签名可以适应不同类型的切片进行排序。