面试题之编程语言规范
一、问题
趋势科技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包调用
通过将fmt合并到当前程序下,可以直接使用Printlnimport ( "fmt" ) func main(){ fmt.Println("fmt.Println") }
import ( . "fmt" // 使用 . 合并 ) func main(){ fmt.Println("fmt.Println") }
- 包重命名,包内命名冲突问题,比如有两个包 package1,package2, package2 下有一个对整型做加运算的Add方法,package2 下有一个对float32做加运算的Add方法,两个方法相同,如果都在当前程序下导入两个包,就会出错,如下
可以采用重命名的方式对包引入当前程序空间内的时候修改包名。在python中,比如import ( "package1" "package2" )
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捕获
- 错误描述如果是英文必须为小写,不需要标点结尾
- 采用独立的错误流进行处理
posted on 2022-06-06 11:34 weilanhanf 阅读(126) 评论(0) 编辑 收藏 举报