Skip to content

golearnku/go-practice

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

  • 现有整型数组 a 、整型数组 b、以及整型v。请使用指定编程语言编写函数,判 断是否可以从 a 中选择一个数,b 中选择一个数,二者相加等于 v,如可以返回 true ,否则返回 false 。比如
a = [10, 40, 5, 280];
b = [234, 5, 2, 148, 23]; v = 42;

将返回 true,因为a中40和b中2相加为42。

package main

import (
	"fmt"
)

func main() {
	nums := []int{10, 40, 5, 280}
	nums2 := []int{234, 5, 2, 148, 23}
	target := 42
	fmt.Println(twoSum2(nums, nums2, target))
}

func twoSum2(nums, nums2 []int, target int) bool {
	arr := make([]int, 0, len(nums)+len(nums2))
	arr = append(arr, nums...)
	arr = append(arr, nums2...)
	m := map[int]int{}
	for _, val := range arr {
		if _, ok := m[target-val]; ok {
			return true
		}
		m[val] = val
	}
	return false
}
  • 现要求游戏玩家的用户名是 user 后加上不重复且随机的正整数,请参考 PostgreSQL 中 pseudo_encrypt() 的原理,使用指定编程语言,实现一个高效的用户名生成算法。
package main

import (
	"fmt"
	"math"
	"strconv"
)

func main() {
	for i := 1000; i <= 9999; i++ {
		fmt.Println("user_" + strconv.FormatInt(PseudoEncrypt(int64(i)), 10))
	}
}

// PseudoEncrypt
func PseudoEncrypt(value int64) int64 {
	var (
		l1, l2, r1, r2 int64
	)

	l1 = (value >> 16) & 0xffff
	r1 = value & 0xffff
	for i := 0; i < 3; i++ {
		l2 = r1
		r := math.Round(float64((1366 * r1 + 150889) % 714025) / 714025.0 * 32767)
		r2 = l1 ^ int64(r)
		l1 = l2
		r1 = r2
	}
	return (r1 << 16) + l1
}
  • 如果要求用户名均为8位,并且即便知道所用算法,也无法预测用户名序列,应该如何改进算法?

答:

package main

import (
    "fmt"
	"math"
	"strconv"
)

func main() {
	for i := 10000000; i <= 20000000; i++ {
		idxStr := DecimalToAny(PseudoEncrypt(int64(i)), 64)
		for i, l := 0, 8-len(idxStr); i < l; i++ {
			idxStr = "u" + idxStr
		}
		userName := "user_" + idxStr
		fmt.Printf("随机生成的用户名: %s\n", userName)
	}
}

// PseudoEncrypt
// 参考 Pseudo encrypt 算法:https://wiki.postgresql.org/wiki/Pseudo_encrypt
func PseudoEncrypt(value int64) int64 {
	var (
		l1, l2, r1, r2 int64
	)

	l1 = (value >> 16) & 65535
	r1 = value & 65535
	for i := 0; i < 3; i++ {
		l2 = r1
		r := math.Round(float64((1366*r1+150889)%714025) / 714025.0 * 32767)
		r2 = l1 ^ int64(r)
		l1 = l2
		r1 = r2
	}
	return (r1 << 16) + l1
}

// DecimalToAny 10 进制转换为任意进制
func DecimalToAny(num int64, n int) string {
	var tenToAny = map[int64]string{
		0: "0", 1: "1", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "a", 11: "b", 12: "c", 13: "d", 14: "e", 15: "f", 16: "g", 17: "h", 18: "i", 19: "j", 20: "k", 21: "l", 22: "m", 23: "n", 24: "o", 25: "p", 26: "q", 27: "r", 28: "s", 29: "t", 30: "u", 31: "v", 32: "w", 33: "x", 34: "y", 35: "z", 36: "A", 37: "B", 38: "C", 39: "D", 40: "E", 41: "F", 42: "G", 43: "H", 44: "I", 45: "J", 46: "K", 47: "L", 48: "M", 49: "N", 50: "O", 51: "P", 52: "Q", 53: "R", 54: "S", 55: "T", 56: "U", 57: "V", 58: "W", 59: "X", 60: "Y", 61: "Z",
	}
	newNumStr := ""
	var remainder int64
	var remainderString string
	for num != 0 {
		remainder = num % int64(n)
		if 62 > remainder && remainder > 9 {
			remainderString = tenToAny[remainder]
		} else {
			remainderString = strconv.FormatInt(remainder, 10)
		}
		newNumStr = remainderString + newNumStr
		num = num / int64(n)
	}
	return newNumStr
}

想到另外一种方案,使用预生成的方式,基于 redis 的 list 存储,每次获取的时候 pop 一个出来就行了.

  • 请设计系统和协议,使用以上算法,实现手机用户的注册和登录,要求能够实现 用户名与设备的绑定,并应对 10万用户/小时 的注册和登录压力,系统应具有横 向扩展能力。

答: 首先没太理解是 设置的系统要每小时能支撑10万用户注册,还是峰值要能支撑10万用户注册,如果是要求每小时能支撑10万用户注册,那么平均到每秒注册用户就是:100000 / 3600 约等于 1 秒有 28 个用户注册; 所以对系统的要求不是很大,一般的系统都能支持这个体量。如果是峰值 10万用户注册,可能这 10w 用户发生在某一段时间内,这时候 需要给服务增加限流机制,避免整个服务不可用。

  • 请改进系统设计,允许用户更换手机时保留账号。

    设计的注册和登录请查看 user_server 目录

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published