当前位置: 首页 > 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/239124.html

相关文章:

  • 怎么自己学着做网站麒麟seo
  • 阿里巴巴网站的建设内容日本今日新闻头条
  • 北京网站建设外包公司黄石seo
  • 潍坊高端网站开发怎么进行网站推广
  • 互联网公司网站源码seo零基础教学视频
  • app渠道推广百度关键词优化教程
  • 哪些网站可以在线做动图seo专业培训中心
  • 池州网站制作新闻最新消息
  • 九斗云网络推广营销数据惠州seo排名
  • 城市宣传网站建设方案长春关键词优化公司
  • 淘宝客网站虚拟主机付费推广
  • 石家庄哪里做微网站微信朋友圈广告30元 1000次
  • wordpress商城微信广东知名seo推广多少钱
  • 怎么弄公司网站上海短视频推广
  • 蓝色系的网站网络营销案例题
  • 9377将军传奇seo外包公司报价
  • 湘潭网站优化今日头条指数查询
  • 快盘做网站服务器百度地图疫情实时动态
  • 怎么自己做刷赞网站中国网民博客 seo
  • 没有备案的网站能否帮网上支付百度免费推广
  • 网站介绍怎么写百度电脑版
  • 网站整合推广seo外包方案
  • 西安做网站的公司seo诊断报告怎么写
  • 潍坊做网站价格磁力搜索器 磁力猫
  • 用phython做网站太原关键词优化服务
  • 优秀企业门户网站建设站长域名查询工具
  • 用dedecms 做门户网站百度推广优化工具
  • 怎么在jsp网站做验证码色目人
  • 银川网站建设nx110网站建设图片
  • 网站建设域名怎么用什么是seo搜索引擎优化