当前位置: 首页 > wzjs >正文

大鹏网站建设在线网页服务器

大鹏网站建设,在线网页服务器,为新创业公司建设网站,公众号平台登录官网简介 工作一年多了,天天CRUD,终于以前学习的算法排上用场了。 背景 我们的系统在用户注册时没有校验身份id(身份证)和电话号码的唯一,可能使用相同的身份id或者电话号码创建多个账号,导致有些人开多个账…

简介

工作一年多了,天天CRUD,终于以前学习的算法排上用场了。

背景

我们的系统在用户注册时没有校验身份id(身份证)和电话号码的唯一,可能使用相同的身份id或者电话号码创建多个账号,导致有些人开多个账号领多份钱。现在公司想降本增效,让我统计出各个市场存在相同身份id或者电话号码的账号信息。

输入

两张表已过滤本次统计不涉及的字段
ops_tab
(operator 是站点员工表)
在这里插入图片描述

staff_tab
(员工表,里面包含的信息更详细。staff包括operator和driver,因此ops_tab的数据是staff_tab的子集)
在这里插入图片描述
ops_tab没有PassportId,因此需要拿staff Id去staff_tab获取对应passport id。

另外各个市场判断账号是否来自于同一个人是有差别的,有些市场允许多个账号使用同一个电话号码。

市场判断条件
印度尼西亚ID1、PassportId 2、Phone Number
马来西亚MY1、PassportId 2、Phone Number
菲律宾PH1、PassportId 2、Phone Number
新加坡SG1、PassportId 2、Phone Number
泰国TH1、Phone Number
台湾TW1、PassportId
越南VN1、PassportId 2、Phone Number

比如印度尼西亚就不允许Passport Id和电话号码重复,而泰国允许Passport Id重复而电话号码不能重复。

输出

输出excel,相同信息在同一个组,只统计存在重复信息的账号,不重复的不需要展示。
在这里插入图片描述

详细设计

流程图
在这里插入图片描述

golang实现

算法主体

func Run(opsList []*OpsTab, staffList []*StaffTab) {cid := strings.ToUpper(os.Getenv("CID"))fmt.Println(cid)if len(cid) == 0 {return}NewExcelListWithOpsAndStaff(opsList, staffList).Group(cid).Export(cid)
}type OpsTab struct {Id             uint64 `gorm:"column:id" json:"id"`OpsId          string `gorm:"column:ops_id" json:"ops_id"`OpsName        string `gorm:"column:ops_name" json:"ops_name"`Phone          string `gorm:"column:phone" json:"phone"`OpsStatus      int    `gorm:"column:ops_status" json:"ops_status"`StaffId        string `gorm:"column:staff_id" json:"staff_id"`
}type StaffTab struct {StaffId         string `gorm:"column:staff_id" json:"staff_id"`PassportId      string `gorm:"column:passport_id" json:"passport_id"`
}// 根据staff_id将Ops_tab和staff_tab合并成一个结构体
type ExcelResultItem struct {OpsName    stringOpsId      stringStaffId    stringPhone      stringPassportId stringOpsStatus  int
}type ExcelList []*ExcelResultItemfunc NewExcelListWithOpsAndStaff(opsList []*OpsTab, staffList []*StaffTab) *ExcelList {return (&ExcelList{}).toExcelResultItemList(opsList, staffList)
}func NewExcelList() *ExcelList {return &ExcelList{}
}func (e *ExcelList) Append(item *ExcelResultItem) {*e = append(*e, item)
}func (e *ExcelList) Size() int {return len(*e)
}func (e *ExcelList) toExcelResultItemList(opsList []*OpsTab, staffList []*StaffTab) *ExcelList {staffId2StaffMap := make(map[string]*StaffTab)for _, item := range staffList {staffId2StaffMap[item.StaffId] = item}for _, item := range opsList {passportId := ""if staff, ok := staffId2StaffMap[item.StaffId]; ok {passportId = staff.PassportId}*e = append(*e, &ExcelResultItem{OpsName:    item.OpsName,OpsId:      item.OpsId,StaffId:    item.StaffId,Phone:      item.Phone,PassportId: passportId,OpsStatus:  item.OpsStatus,})}return e
}func (e *ExcelList) Group(cid string) *GroupedExcelList {excelItemList := *euf := NewPathCompressionUnionFind(len(excelItemList))for i := range excelItemList {for j := i + 1; j < len(excelItemList); j++ {if handler.Check(cid, excelItemList[i], excelItemList[j]) {uf.Union(i, j)}}}ufId2ExcelListMap := make(map[int]*ExcelList)for id, item := range excelItemList {root := uf.Find(id)if uf.GetSize(root) < 2 {continue}if _, ok := ufId2ExcelListMap[root]; !ok {ufId2ExcelListMap[root] = NewExcelList()}ufId2ExcelListMap[root].Append(item)}res := NewGroupedExcelList()for _, list := range ufId2ExcelListMap {res.Append(list)}return res
}type GroupedExcelList []*ExcelListfunc NewGroupedExcelList() *GroupedExcelList {return &GroupedExcelList{}
}func (g *GroupedExcelList) Append(list *ExcelList) {*g = append(*g, list)
}

校验是否重复(策略模式)

检查是否重复策略模式UML
类似这个,实际简单一点

var handler = NewCheckWhetherSameStrategyHandler()type CheckWhetherSameStrategyHandler struct {region2StrategyMap map[string]CheckWhetherSameStrategy
}func NewCheckWhetherSameStrategyHandler() *CheckWhetherSameStrategyHandler {return &CheckWhetherSameStrategyHandler{region2StrategyMap: make(map[string]CheckWhetherSameStrategy),}
}func (c *CheckWhetherSameStrategyHandler) Register(cid string, strategy CheckWhetherSameStrategy) {c.region2StrategyMap[cid] = strategy
}func (c *CheckWhetherSameStrategyHandler) Check(cid string, ops1, ops2 *ExcelResultItem) bool {if _, ok := c.region2StrategyMap[cid]; !ok {panic(fmt.Sprintf("cid[%v] not exist", cid))}return c.region2StrategyMap[cid].Check(ops1, ops2)
}type CheckWhetherSameStrategy interface {Check(ops1, ops2 *ExcelResultItem) bool
}type CheckWhetherSameStrategyID struct{}func (c *CheckWhetherSameStrategyID) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategyMY struct{}func (c *CheckWhetherSameStrategyMY) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategyPH struct{}func (c *CheckWhetherSameStrategyPH) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategySG struct{}func (c *CheckWhetherSameStrategySG) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategyTH struct{}func (c *CheckWhetherSameStrategyTH) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategyTW struct{}func (c *CheckWhetherSameStrategyTW) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId
}type CheckWhetherSameStrategyVN struct{}func (c *CheckWhetherSameStrategyVN) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}func init() {handler.Register("ID", &CheckWhetherSameStrategyID{})handler.Register("MY", &CheckWhetherSameStrategyMY{})handler.Register("PH", &CheckWhetherSameStrategyPH{})handler.Register("SG", &CheckWhetherSameStrategySG{})handler.Register("TH", &CheckWhetherSameStrategyTH{})handler.Register("TW", &CheckWhetherSameStrategyTW{})handler.Register("VN", &CheckWhetherSameStrategyVN{})
}

golang Excel导出操作

在这里插入图片描述

func (g *GroupedExcelList) Export(cid string) {//创建excel文件xlsx := excelize.NewFile()sheet := fmt.Sprintf("same_field_ops_%v_excel", cid)//创建新表单index := xlsx.NewSheet(sheet)//第一行  各个字段的名称row := 1setFieldValue2Excel(xlsx, sheet, row, FieldNameGroup, FieldNameGroup)setFieldValue2Excel(xlsx, sheet, row, FieldNameOpsName, FieldNameOpsName)setFieldValue2Excel(xlsx, sheet, row, FieldNameOpsId, FieldNameOpsId)setFieldValue2Excel(xlsx, sheet, row, FieldNamePhoneNumber, FieldNamePhoneNumber)setFieldValue2Excel(xlsx, sheet, row, FieldNamePassportId, FieldNamePassportId)setFieldValue2Excel(xlsx, sheet, row, FieldNameStatus, FieldNameStatus)row++for groupId, listPtr := range *g {//Excel 一组list := *listPtrstartRow := rowrow++for _, item := range list {//Excel 一行setFieldValue2Excel(xlsx, sheet, row, FieldNameGroup, fmt.Sprintf("%v", groupId))setFieldValue2Excel(xlsx, sheet, row, FieldNameOpsName, item.OpsName)setFieldValue2Excel(xlsx, sheet, row, FieldNameOpsId, item.OpsId)setFieldValue2Excel(xlsx, sheet, row, FieldNamePhoneNumber, item.Phone)setFieldValue2Excel(xlsx, sheet, row, FieldNamePassportId, item.PassportId)setFieldValue2Excel(xlsx, sheet, row, FieldNameStatus, fmt.Sprintf("%v", item.OpsStatus))row++}//合并A列成一组xlsx.MergeCell(sheet, fmt.Sprintf("A%v", startRow), fmt.Sprintf("A%v", row - 1))}//设置默认打开的表单xlsx.SetActiveSheet(index)//保存文件到指定路径err := xlsx.SaveAs(fmt.Sprintf("./%v.xlsx", sheet))if err != nil {log.Fatal(err)}
}type FieldName = stringconst (FieldNameGroup       FieldName = "Group"FieldNameOpsName     FieldName = "Ops Name"FieldNameOpsId       FieldName = "Ops Id"FieldNamePhoneNumber FieldName = "Phone Number"FieldNamePassportId  FieldName = "Passport Id"FieldNameStatus      FieldName = "Status"
)
//如图,表格上角的ABCDEF
var posMap = map[FieldName]string{FieldNameGroup:       "A",FieldNameOpsName:     "B",FieldNameOpsId:       "C",FieldNamePhoneNumber: "D",FieldNamePassportId:  "E",FieldNameStatus:      "F",
}func setFieldValue2Excel(xlsx *excelize.File, sheet string, row int, key FieldName, val string) {if _, err := strconv.ParseInt(val, 10, 64); len(val) > 1 && err == nil {val = "'" + val}xlsx.SetCellValue(sheet, fmt.Sprintf("%v%v", posMap[key], row), val)
}

路径压缩并查集

type PathCompressionUnionFind struct {parents []intsize    []int
}func NewPathCompressionUnionFind(len int) *PathCompressionUnionFind {parents := make([]int, len)size := make([]int, len)for i := range parents {parents[i] = isize[i] = 1}return &PathCompressionUnionFind{parents: parents,size:    size,}
}func (t *PathCompressionUnionFind) Union(p, q int) {pRoot := t.Find(p)qRoot := t.Find(q)if pRoot == qRoot {return}t.parents[qRoot] = t.parents[pRoot]t.size[pRoot] += t.size[qRoot]
}func (t *PathCompressionUnionFind) Find(p int) int {for t.parents[p] != p {t.parents[p] = t.parents[t.parents[p]]p = t.parents[p]}return p
}func (t *PathCompressionUnionFind) GetSize(p int) int {if p < 0 || p >= len(t.parents) {panic("Union Find Array out of bounds")}return t.size[t.Find(p)]
}

复杂度

时间复杂度
O(N^2)

空间复杂度
O(N)

其他

从k8s pod上连接数据库并下载表数据

我们线上数据数据量约200万,从公司提供的平台查会被限制单词1000条数据,因此下载ops_tab和staff_tab的数据需要写个脚本在k8s上执行。

本地(MAC)
安装交叉编译环境

brew install FiloSottile/musl-cross/musl-cross

切换到main函数所在包,执行编译

CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CGO_LDFLAGS="-static" go build

压缩并拆分为多个文件方便上传

tar cjf - $your_name$ |split -b 5m - $your_name$.tar.bz2.

在k8s pod上
安装上传插件

apt install -y lrzsz

安装解压插件

apt install -y bzip2

上传文件

rz

给文件赋执行权限

chmod +x $your_name$

运行

./$your_name$
http://www.dtcms.com/wzjs/521154.html

相关文章:

  • 吴江公司网站建设电话江西网络推广seo
  • wordpress 轮播开发哈尔滨优化调整人员流动管理
  • centos wordpress 优化常德seo招聘
  • 在线做ppt模板下载网站谷歌广告平台
  • 优化网站推广教程排名微商怎样让客源主动加你
  • p2p网上贷款网站建设方案.docx附近有没有学电脑培训的
  • 包头建设网站搜索引擎广告的优缺点
  • 临沂做网站建设的公司哪家好宁波最好的seo外包
  • 特种设备作业人员证查询seo专员工资待遇
  • 网站挂服务器后图片不显示互联网推广营销方案
  • 济南教育平台网站建设免费个人主页网站
  • 如何销售网站开发苹果看国外新闻的app
  • 长春网站开发公司搜狗识图
  • 泰安网站建设哪家快百度提问
  • 广西城乡建设委员会网站百度合伙人答题兼职赚钱
  • 搜索引擎友好的网站有哪些特点seo怎么去优化
  • 网站优化培训学校移投界seo
  • 公司网站后台维护怎么做seo查询系统
  • 最好的开发网站建设价格谷歌google地图
  • 湖南智慧住建云官网百度seo新算法
  • wordpress后台如何登录福州短视频seo网红
  • 网站后台怎么上传表格附近的计算机培训班
  • 自己做的网站显示iis7seo优化按天扣费
  • 深圳网站建设网页设计网络营销的作用
  • 怎么分析网站用什么技术做的企业网站推广
  • 什么是网络营销?如何理解网络营销的内涵seo排名点击器曝光行者seo
  • 网站banner动图怎么做网站及推广
  • 毕业设计网站设计步骤关键词优化的发展趋势
  • 软件开发流程的五大步骤网络优化工程师是干什么的
  • 哪些网站是用h5做的网站开发制作培训学校