• 面试题之编程语言规范


    一、问题

    趋势科技golang/python暑期软开实习一面

    面试官:你听说过PEP8规范吧,至少列举5条规范
    面试官:谈谈golang编码规范

    二、PEP8规范

    ​PEP是Python Enhancement Proposal的缩写,通常翻译为“Python增强提案”。​每个PEP都是一份为Python社区提供的指导Python往更好的方向发展的技术文档,其中的第8号增强提案(PEP 8)是针对Python语言编订的代码风格指南。
    语言规范不会影响代码的实际功能,但是好的编程规范,写出可读性强的代码可以保证开发效率和团队协作效率的提升。

    1、一些规范如下

    • 每行缩进最好用4个空格代替tab,不允许tab和空格混用,因为有的编辑器默认的是tab键是两个空格,所以如果tab和空格混用会造成代码格式混乱。
    • 单行最大字符限制79,用\换行。
    • 避免通配符导入,分行导入不同的包,通配符导入有时候无法导入一些特定的变量或者方法,并且多个包都是用通配符导入会有命名冲突的问题。
    • 不要害怕用过长的命名变量,越清楚越好,比如使用is,has等前缀标识bool型变量。
    • 命名用英文,而不是拼音,来提高可读性。
    • 下划线分割英文,提高可读性,python更偏向于使用小写英文与下划线组合的方式标识变量名。
    • 大写字母表示常量
    • 类首字母大写,函数全小写
    • class 的 method 之间一个空行
    • 函数内逻辑无关的段落之间空一行,不要过度使用空行
    • except 要接具体的Exception,使用 finally 子句来处理一些收尾操作
    • 用is代替 == ,is比较的是内存地址,而 == 则需要深入对象字典逐个属性比较,更慢。

    2、PyCharm中的代码规范

    默认的PyCharm中有PEP8代码提示,你敲得代码中不符合规范时,会有下划波浪线提示,想要调整提示级别可以直接在右下角调整 Highlighting Level。

    二、golang中的代码规范

    golang属于静态类型语言,跟python动态类型对比来说,规范更严格一些。

    1、命名规范

    • 当命名(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用。
    • 命名如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的。

    1.1 包名:package

    尽量保持包名和目录名一致,采取简短有意义的小写单词作为包名,避免和标准库冲突重复,不要使用混合大小写和下划线

    package cnblog
    

    1.2 文件名

    也就是包下面的.go文件,采用小写单词+下换线组合的方式

    /cnblog
    ———— user_model.go
    

    1.3 结构体命名

    大驼峰命名法命名结构体,结构体内部使用多个初始化格式

    // 多行申明
    type User struct{
        Username  string
        Email     string
    }
     
    // 多行初始化
    u := User{
        Username: "golang",
        Email:    "golang@163.com",
    }
    

    1.4 接口命名

    命名规则基本和上面的结构体类似,单个函数的结构名以 “er” 作为后缀,例如 Reader , Writer,表示单一职责,只有读或者只有写这种行为。

    type Reader interface {
            Read(p []byte) (n int, err error)
    }
    

    1.5 变量命名

    • 采用大驼峰命名,如果变量包内私有,则首单词小写,比如apiClient。
    • 如果变量为bool类型,也可以以Has,Is等单词开头命名

    1.6 常量命名

    全部以大写单词组成常量名,但是采用下划线分隔单词

    2、注释

    Go提供C风格的/* */块注释和C ++风格的//行注释。行注释是常态;块注释主要显示为包注释,表达式内禁用块注释

    • 单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释
    • 多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾,且不可以嵌套使用,多行注释一般用于包的文档描述或注释成块的代码片段

    2.1 块注释

    每个包都应该有一个包注释,一个位于package子句之前的块注释或行注释。包如果有多个go文件,只需要出现在一个go文件中(一般是和包同名的文件)即可。 包注释应该包含下面基本信息(请严格按照这个顺序,简介,创建人,创建时间):

    • 包的基本简介(包名,简介)
    • 创建者,格式: 创建人: rtx 名
    • 创建时间,格式:创建时间: yyyyMMdd

    2.2 结构体/接口注释

    通常放在接口或者结构体的前一行,对其进行简要介绍,格式为: 结构体名, 结构体说明。同时结构体内的每个成员变量都要有说明,该说明放在成员变量的后面(注意对齐)

    2.3 函数/方法注释

    包括三个部分

    • 简要说明,格式说明:以函数名开头,“,”分隔说明部分
    • 参数列表:每行一个参数,参数名开头,“,”分隔说明部分
    • 返回值: 每行一个返回值

    2.4 代码注释

    • 对局部复杂或者关键位置逻辑采用行内注释
    • 注释内中英文混用时候,采用空格分隔,
    • 单行注释不要过长,不超过120个字符

    3、import规范

    • 避免引入无用的包,与python不同的是,如果导入的包未被使用,golang会编译不通过,而在Pycharm中,如果导入的py包未被使用,仅仅是代码块变暗。
    • 不同类型的包顺序,通常import多行的时候,会自动格式化,如果导入包含多种类型的包,建议有顺序的组织包的顺序。不同类型的包之间采用空行,如果是当前项目的其他包,最好采用相对路径。
      import (
         "标准库"
      
         "项目包"
      
         "第三方包"
      )
      
    • 合并包,用.点号可以将引入的一个包合并到当前程序下
      这里每次使用Println需要通过fmt包调用
      import (
          "fmt"
      )
      func main(){
          fmt.Println("fmt.Println")
      }
      
      通过将fmt合并到当前程序下,可以直接使用Println
        import (
            . "fmt" // 使用 . 合并
        )
        func main(){
            fmt.Println("fmt.Println")
        }
      
    • 包重命名,包内命名冲突问题,比如有两个包 package1,package2, package2 下有一个对整型做加运算的Add方法,package2 下有一个对float32做加运算的Add方法,两个方法相同,如果都在当前程序下导入两个包,就会出错,如下
      import (
        "package1"
        "package2"
      )
      
      可以采用重命名的方式对包引入当前程序空间内的时候修改包名。在python中,比如import package as my_package
      import (
        "fmt"
        int_add "package1"
        float_add "package2"
      )
      func main(){
        fmt.Println(init_add.Add(1, 2))
        fmt.Println(float_add.Add(1, 2))
      }
      
    • 匿名包,引入无用的包的时候会报错,使用 _ 一个下划线可以标识引入的包为匿名引用,虽然不会出现语法错误,但是可能出现一些额外的意想不到的问题。主要原因在于,只要 import 导入一个包,就会自动执行这个包的 init 函数,并且如果一个 package 包下有多个 .go文件,多个 .go文件中都有 init 函数,那么匿名方式导入这个包,不能保证init函数的执行顺序,所以一般不建议一个包包含多个init函数,也不建议使用匿名引用的方法导入包。
      import (
        "fmt"
        _ "package1"
      )
      

    4、错误处理

    golang三个痛点可能就是包管理,异常处理以及泛型,go没有异常类型,只有错误。所以也就是有了这种常见的写法

    str := "123"
    num, err := strconv.Atoi(str)
    if err != nil{
      fmt.Println("strconv.Atoi err: ", err)  // 或者打印日志
      return 
    }
    
    • 错误处理的原则就是不能丢弃任何有返回err的调用,不要使用 _ 丢弃,必须全部处理。接收到错误,要么返回err,或者使用log记录下来
    • 尽早return:一旦有错误发生,马上返回
    • 尽量不要使用panic,如果使用panic,要用recover捕获
    • 错误描述如果是英文必须为小写,不需要标点结尾
    • 采用独立的错误流进行处理
  • 相关阅读:
    Andrew Ng机器学习算法入门((七):特征选择和多项式回归
    Andrew Ng机器学习算法入门((六):多变量线性回归方程求解
    Andrew Ng机器学习算法入门((五):矩阵和向量
    Linux常用命令集锦
    Andrew Ng机器学习算法入门(四):阶梯下降算法
    AZscaaner源码解读之数据库连接(一)
    Andrew Ng机器学习算法入门(三):线性回归算法
    Andrew Ng机器学习算法入门(二):机器学习分类
    MapServer
    fetch.js
  • 原文地址:https://www.cnblogs.com/welan/p/16347626.html
Copyright © 2020-2023  润新知