Spring Cloud配置SSH连接统一配置中心

当时在配置ssh连接的时候不知不觉就掉坑里去了,对一些知识点没完全理解;

先说说的掉坑,复制id_rsa文件内的文本出来,放进bootstrap.ymlprivateKey中,如下图

启动报错

1
2
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'spring.cloud.config.server.git' to org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties failed:
Reason: Property 'spring.cloud.config.server.git.privateKey' is not a valid private key

我们看看官网怎么配spring.cloud.config.server.git

bootstrap.yml

有没有发现不一样,没错,官网配置的privateKey里少了前3行属性
为什么???
因为官网的秘钥在生成时是没有设置秘钥密码的,而我们的秘钥是有密码的,它没办法解密秘钥;
解决办法两种:

  1. ==我们在生成秘钥时也不设置秘钥密码==
  2. ==在yml中配置的git属性添加passphrase==

下面是全配置过程,主要分3步

生成公钥与私钥

打开Git Bash/Terminal,输入ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

引号里面替换成你的邮箱地址或标志自己身份的信息

提示保存秘钥的文件位置,直接回车保持默认位置

设置秘钥密码(直接回车则不设置秘钥密码),生成公钥、秘钥

完成之后可以在/root/.ssh/目录下找到公钥(id_rsa.pub)秘钥(id_rsa)

将公钥添加到git上

复制id_rsa.pub的内容出来

打开github,进入需要拉取文件的仓库,进入设置标签页

点击Add Deploy key

输入GitHub密码确认

刚添加的公钥是灰色的,还没有被使用

在bootstrap.yml中配置

把id_rsa的全部内容复制出来,放到private-key属性

注意:

  1. uri要用ssh形式的地址
  2. ignore-local-ssh-settings设置为true,忽略本地的ssh配置
  3. passphrase内要配置上面设置的秘钥密码

启动项目后,可以在Github的仓库设置中看到公钥已经被使用,变成了绿色。

至此spring-cloud-config使用ssh连接git就配置完成。


修改秘钥密码

打开Git Bash/Terminal,输入 ls-al ~/.ssh 检查之前是否已经生成了SSH key

如果是这样的那就说明已经生成过秘钥,可以选择修改修改私钥密码(passphrase)
输入 ssh-keygen -p

直接回车继续,输入旧密码,然后输入两次新密码

Python 3 实例

  1. 摄氏度转华氏度
1
2
3
a = float(input("输入摄氏度:"))
b = a * 1.8 + 32
print("摄氏度:{}℃ = 华氏度:{}℉".format(a, b))
  1. 求园的面积
1
2
3
r = float(input("输入园半径:"))
area = math.pi*r**2
print("半径为{}的园面积为{}".format(r, area))
  1. 开平方根
1
2
3
num1 = float(input("输入一个数:"))
result = num1 ** 0.5
print("{}开平方={}".format(num1, result))
  1. 求三角形面积
1
2
3
4
5
6
a = float(input("输入边长:"))
b = float(input("输入边长:"))
c = float(input("输入边长:"))
p = (a + b + c) / 2
s = (p * (p - a) * (p - b) * (p - c)) ** 0.5
print("边长为{},{},{} 的三角形面积为{}".format(a, b, c, s))
  1. 判断输入字符串是否为数字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def is_number(s):
"""判断输入字符串是否为数字"""
try:
float(s)
return True
except ValueError:
pass
try:
import unicodedata
for i in s:
unicodedata.numeric(i)
return True
except (ValueError, TypeError):
pass
return False
  1. 判断是否是奇数
1
2
3
4
5
6
7
8
9
10
11
12
def is_odd(n):
"""判断是否是奇数"""
try:
if float(n) % 2 == 1:
print("奇数")
return True
else:
print("偶数")
except ValueError:
print("参数错误")
pass
return False
  1. 判断是否为闰年
1
2
3
4
5
6
7
8
9
10
11
def is_leap_year(year):
"""判断是否为闰年"""
try:
year = float(year)
if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
return True
else:
return False
except ValueError:
print("参数错误")
pass
  1. 获取最大值
1
2
3
def max_num(s):
"""获取最大值"""
return max(s)
  1. 判断是否为质数
1
2
3
4
5
6
7
8
9
10
11
def is_prime(num):
"""判断是否为质数"""
try:
num = int(num)
for i in range(2, num):
if num % i == 0:
return False
else:
return True
except ValueError:
pass
  1. 输出指定范围内的质数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def scope_prime(min, max):
"""输出指定范围内的质数"""
try:
min = int(min)
max = int(max)
prime = set()
for i in range(min, max + 1):
for j in range(2, i):
if i % j == 0:
break
else:
prime.add(i)
return prime
except (TypeError, ValueError):
pass
  1. 阶乘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def factorial(num):
"""阶乘"""
try:
num = int(num)
if num == 1:
return 1
else:
# 递归实现
return num * factorial(num - 1)
# 非递归实现
# factorial = 1
# for i in range(1, num + 1):
# factorial *= i
# return factorial
except(TypeError, ValueError):
pass
  1. 乘法表
1
2
3
4
5
6
def get_multiplication():
"""乘法表"""
for i in range(1, 10):
for j in range(1, i + 1):
print("{}x{}={}\t".format(i, j, i * j), end="")
print()
  1. 斐波那契数列
1
2
3
4
5
6
7
8
def get_fibonacci(n):
"""斐波那契数列(0,1,1,2,3,5..)"""
fib_list = [0, 1]
if n == 1:
return [0, ]
for i in range(2, n):
fib_list.append(fib_list[i - 2] + fib_list[i - 1])
return fib_list
  1. 阿姆斯特朗数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def get_armstrong(n):
"""阿姆斯特朗数"""
a = []
b = []
for i in range(1, n + 1):
temp = i
count = 0
sum_num = 0
a.clear()
while int(temp % 10) != 0 or int(temp / 10) != 0:
a.append(int(temp % 10))
temp /= 10
count += 1
for j in iter(a):
sum_num += j ** count
if sum_num == i:
b.append(i)
return b
  1. 进制转
1
2
3
4
5
6
7
8
9
10
11
def change_type(num):
# 十进制转二进制
print("二进制为:{}".format(bin(num)))
# 十进制转八进制
print("八进制为:{}".format(oct(num)))
# 十进制转十六进制
print("十六进制为:{}".format(hex(num)))
# 字符转ASCII码
print("ASCII码为:{}".format(ord(num)))
# ASCII码转字符
print("字符为:{}".format(chr(num)))
  1. 最大公约数
1
2
3
4
5
6
7
8
def get_max_divisor(x, y):
"""最大公约数"""
if x > y:
x, y = y, x
for i in range(1, x + 1):
if x % i == 0 and y % i == 0:
divisor = i
return divisor
  1. 最小公倍数
1
2
3
4
5
6
7
8
def get_min_multiple(x, y):
"""最小公倍数"""
if x < y:
x, y = y, x
multiple = y
while multiple % x != 0 or multiple % y != 0:
multiple += 1
return multiple
  1. 日历
1
2
3
def my_calendar(year, month):
"""日历"""
print(calendar.month(year, month))
  1. 递归 斐波那契数列
1
2
3
4
5
6
def recur_fibo(n):
"""递归 斐波那契数列"""
if n <= 1:
return n
else:
return recur_fibo(n - 1) + recur_fibo(n - 2)
  1. 文件输入输出
1
2
3
4
5
6
7
def file_test(file_name, my_input):
"""文件输入输出"""
with open(file_name, 'w+') as file:
file.write(my_input)
with open(file_name, 'r') as file:
output = file.read()
return output
  1. 字符串大小写转换
1
2
3
4
5
6
7
def up2down_or_down2up(my_str):
"""字符串大小写转换"""
my_str = str(my_str)
print(my_str.upper())
print(my_str.lower())
print(my_str.title())
print(my_str.capitalize())
  1. 获得昨天日期
1
2
3
4
5
6
def get_yesterday():
"""获得昨天日期"""
today = datetime.date.today()
one_day = datetime.timedelta(days=1)
yesterday = today - one_day
return yesterday
  1. 约瑟夫环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def joseph():
"""约瑟夫环"""
people = []
for i in range(0, 30):
# 1,在船上,0,落水
people.append(1)
# 报数
check = 0
# 落水人数
num = 0
# 指针
index = -1
while num < 15:
# 报数
check = check + 1
index = index + 1
index = index % 30
while people[index] == 0:
index = index + 1
index = index % 30
if check == 9:
people[index] = 0
print('{}号下船'.format(index + 1))
num = num + 1
check = 0
# print(str(people))
1
2
3
4
5
6
7
8
9
def joseph2():
"""约瑟夫环"""
people = list(range(30))
while len(people) > 15:
i = 1
while i < 9:
people.append(people.pop(0))
i += 1
print('{:2d}号下船了'.format(people.pop(0)))
  1. 秒表功能实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def stopwatch():
"""秒表功能实现"""
print('按下回车开始计时,按下Ctrl+c停止计时')
while True:
try:
input()
starttime = time.time()
print('开始')
while True:
print('计时:', round(time.time() - starttime, 0), '秒', end='\r')
time.sleep(1)
except KeyboardInterrupt:
print('结束')
endtime = time.time()
print('总共的时间为:', round(endtime - starttime, 2), 'secs')
break
  1. 计算n个自然数的立方和
1
2
3
def cube_sum(n):
"""计算n个自然数的立方和"""
return sum([num ** 3 for num in range(1, n + 1)])
  1. 数组翻转指定个数元素
1
2
3
4
5
6
def list_flip(arr, n):
"""数组翻转指定个数元素"""
arr = list(arr)
for i in range(n):
arr.append(arr.pop(0))
return arr
  1. 数组首尾对调
1
2
3
4
def list_exchange(arr):
"""数组首尾对调"""
arr[0], arr[len(arr) - 1] = arr[len(arr) - 1], arr[0]
return arr
  1. 指定位置对调
1
2
3
4
5
6
7
8
9
10
def list_exchange(arr, x, y):
# 数组指定位置对调
arr[x], arr[y] = arr[y], arr[x]
# 判断数组中是否有3
if 3 in arr:
print("数组中包含3")
# 计算数组中元素出现的次数
print('数组中元素2出现了:{}次'.format(arr.count(2)))
# 翻转数组
return [ele for ele in reversed(arr)]
  1. 正则表达式获取字符串中的url
1
2
3
4
5
def get_url(str):
"""正则表达式获取字符串中的url"""
exp = r'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+'
url = re.findall(exp, str)
return url
  1. 按key/value排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def sort_dic():
"""按key/value排序"""
key_value = {2: 56, 1: 2, 5: 12, 4: 24, 6: 18, 3: 323}
key_value2 = {7: 23, 8: 54}
print("按key排序")
print(sorted(key_value.items()))
# for i in sorted(key_value):
# print((i, key_value[i]), end=' ')
print("\n按value排序")
print(sorted(key_value.items(), key=lambda kv: (kv[1], kv[0])))
print("字典值之和为:{}".format(sum(key_value.values())))
# 将字典2加入字典1
key_value.update(key_value2)
print("两字典合并,key_value:{}, key_value2:{}".format(key_value, key_value2))
  1. 时间转换
1
2
3
4
5
6
7
8
9
10
11
a1 = "2019-7-20 23:40:00"

# 先转换为时间数组
timeArray = time.strptime(a1, "%Y-%m-%d %H:%M:%S")
# 转换为时间戳
timeStamp = int(time.mktime(timeArray))
print(timeStamp)
# 格式转换 - 转为 /
otherStyleTime = time.strftime("%Y/%m/%d %H:%M:%S", timeArray)
print(otherStyleTime)
print("now:{}".format(datetime.datetime.now()))
  1. 二分查找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def binary_search(arr, x):
"""二分查找,在有序数组arr中查找x所在的索引,找不到时返回-1"""
left, right = 0, len(arr) - 1
while True:
if right - left == 1:
if arr[right] == x:
return right
elif arr[left] == x:
return left
else:
return -1
else:
mid = int((right + left) / 2)
if x == arr[mid]:
return mid
elif x > arr[mid]:
left = mid
continue
elif x < arr[mid]:
right = mid
continue
  1. 线性查找
1
2
3
4
5
6
def linear_search(arr, c):
"""线性查找"""
for i in range(len(arr)):
if arr[i] == c:
return i
return -1
  1. 打印杨辉三角
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def pascal_triangles(n):
triangles = {}
n += 1
"""杨辉三角"""
for i in range(1, n):
for j in range(1, i + 1):
ij = str(i) + str(j)
if j == 1:
triangles[ij] = 1
print(" " * (n - i - 1), end='')
print(1, end='')
elif j == i:
triangles[ij] = 1
print(1, end='')
else:
ul = str(i - 1) + str(j - 1)
ur = str(i - 1) + str(j)
triangles[ij] = triangles[ul] + triangles[ur]
print(triangles[ij], end='')
print(" ", end='')
print()
return triangles
  1. 白鸡百钱
1
2
3
4
5
6
7
8
9
def chicken_question():
"""百鸡百钱"""
"""
鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
"""
for x in range(0, 101):
for y in range(0, 101):
if 5 * x + 3 * y + (100 - x - y) / 3 == 100:
print("鸡翁:{}、鸡母:{}、鸡雏:{}".format(x, y, 100 - x - y))
  1. 完全数
1
2
3
4
5
6
7
8
9
10
11
12
def perfect_number(n):
"""完全数"""
temp = []
perfect = []
for i in range(1, n):
for j in range(1, i):
if i % j == 0 and i != j:
temp.append(j)
if sum(temp) == i:
perfect.append(i)
temp.clear()
return perfect
小游戏
Craps赌博游戏

玩家摇两颗色子 如果第一次摇出7点或11点 玩家胜
如果摇出2点 3点 12点 庄家胜 其他情况游戏继续
玩家再次要色子 如果摇出7点 庄家胜
如果摇出第一次摇的点数 玩家胜
否则游戏继续 玩家继续摇色子
玩家进入游戏时有1000元的赌注 全部输光游戏结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import random

money = 1000
while money > 0:
bet = int(input("请下注:"))
while bet > money or bet <= 0:
bet = int(input("请重新下注:"))
money -= bet
first_num = random.randint(2, 12)
print("第一次:{}".format(first_num))
if first_num in [7, 11]:
money += bet * 2
print("1.玩家胜出,获得:{},剩余金币:【{}】".format(bet * 2, money))
continue
elif first_num in [2, 3, 12]:
print("2.庄家胜出,重新开始,剩余金币:【{}】".format(money))
continue
else:
while True:
next_num = random.randint(2, 12)
print("这一次:{}".format(next_num))
if next_num == 7:
print("3.庄家胜出,重新开始,剩余金币:【{}】".format(money))
break
elif next_num == first_num:
money += bet * 2
print("4.玩家胜出,获得:{},剩余金币:【{}】".format(bet * 2, money))
break
# input()
print("金币为零,游戏结束")
21点

基于Python-100-Days的扑克游戏编写

游戏规则(简化版):

​ 开局时,庄家给每个玩家(又称闲家)牌面向上发两张牌(明牌),再给庄家自己发两张牌,一张明牌,一张暗牌(牌面朝下)。
​ 当所有的初始牌分发完毕后,如果玩家拿到的是A和T(无论顺序),就拥有黑杰克(Black Jack);若庄家的明牌为T,且暗牌为A,应直接翻开并拥有Black Jack;如果庄家没有Black Jack则保持暗牌,玩家继续游戏。若玩家为Black Jack且庄家为其他,玩家赢得1.5倍(或2倍,1赔2时)赌注;若庄家为Black Jack且玩家为其他,庄家赢得赌注;若庄家和玩家均为Black Jack,平局,玩家拿回自己的赌注。
​ 接下来是正常的拿牌流程:首名非黑杰克玩家选择拿牌(Hit)、停牌(Stand)、加倍(Double)或投降(Surrender,庄家赢得一半赌注);若选择拿牌,则后续只能选择拿牌或停牌。在发牌的过程中,如果玩家的牌点数的和超过21,玩家就输了——叫爆掉(Bust),庄家赢得赌注(无论庄家之后的点数是多少)。假如玩家没爆掉,又决定不再要牌了(停牌,或因加倍、投降而终止),则轮到下一名非黑杰克玩家选择。
​ 当所有玩家停止拿牌后,庄家翻开暗牌,并持续拿牌直至点数不小于17(若有A,按最大而尽量不爆计算)。假如庄家爆掉了,那他就输了,玩家赢得1倍赌注;否则那么比点数大小,大为赢。点数相同为平局,玩家拿回自己的赌注。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
import random


class Card(object):
"""一张牌"""

def __init__(self, suite, face):
self._suite = suite
self._face = face

@property
def face(self):
return self._face

@property
def suite(self):
return self._suite

def __str__(self):
if self._face == 1:
face_str = 'A'
elif self._face == 11:
face_str = 'J'
elif self._face == 12:
face_str = 'Q'
elif self._face == 13:
face_str = 'K'
else:
face_str = str(self._face)
return '%s%s' % (self._suite, face_str)

def __repr__(self):
return self.__str__()


class Poker(object):
"""一副牌"""

def __init__(self):
self._cards = [Card(suite, face)
for suite in '♠♥♣♦'
for face in range(1, 14)]
self._current = 0

@property
def cards(self):
return self._cards

def shuffle(self):
"""洗牌(随机乱序)"""
self._current = 0
random.shuffle(self._cards)

@property
def next(self):
"""发牌"""
card = self._cards[self._current]
self._current += 1
return card

@property
def has_next(self):
"""还有没有牌"""
return self._current < len(self._cards)


class Player(object):
"""玩家"""

def __init__(self, name):
self._name = name
self._cards_on_hand = []

@property
def name(self):
return self._name

@property
def cards_on_hand(self):
return self._cards_on_hand

def get(self, card):
"""摸牌"""
self._cards_on_hand.append(card)

def arrange(self, card_key):
"""玩家整理手上的牌"""
self._cards_on_hand.sort(key=card_key)


# 排序规则-先根据花色再根据点数排序
class Black_Jack(Player):
"""21点"""

def __init__(self, name):
super().__init__(name)
# 停牌
self._stand = False
# 爆掉
self._bust = False

@property
def stand(self):
return self._stand

@stand.setter
def stand(self, state):
"""停牌"""
self._stand = state

@property
def bust(self):
return self._bust

@bust.setter
def bust(self, state):
"""爆掉"""
self._bust = state

def is_stand(self):
"""是否停牌"""
return self.black_jack_total() == 21 or self.face_total() >= 17

def is_bust(self):
"""是否爆掉"""
return self.face_total() > 21

def open_hand(self, i):
"""明牌"""
return self.cards_on_hand[i]

def clean_hand(self):
"""清空手牌并清空状态"""
self.cards_on_hand.clear()
self.stand = False
self.bust = False

def face_total(self):
"""手牌总点数"""
temp = [card.face for card in self.cards_on_hand]
j_count = temp.count(11)
q_count = temp.count(12)
k_count = temp.count(13)
total = sum(temp) - j_count - q_count * 2 - k_count * 3
return total

def black_jack_total(self):
"""21点计数"""
temp = [card.face for card in self.cards_on_hand]
a_count = temp.count(1)
j_count = temp.count(11)
q_count = temp.count(12)
k_count = temp.count(13)
total = sum(temp) - j_count - q_count * 2 - k_count * 3
for i in range(a_count):
if total < 21:
total += 10
if total > 21:
total -= 10
return total


class Black_Jack_Player(Black_Jack):
"""21点玩家"""

def __init__(self, name):
super().__init__(name)
# 玩家初始赌注
self._money = 1000
# 下注额
self._bet = 0

@property
def money(self):
return self._money

@money.setter
def money(self, money):
"""下注"""
self._money = money

@property
def bet(self):
return self._bet

@bet.setter
def bet(self, bet):
"""下注"""
self._bet = bet

def double(self):
"""加倍"""
self._bet *= 2

def surrender(self):
"""投降"""
self._bet /= 2

def __str__(self):
return "【%s】筹码:%d,点数:%d,牌面:%s" % (
self._name, self._money, self.black_jack_total(), self.cards_on_hand)


class Banker(Black_Jack):
"""庄家"""

def __init__(self, name):
super().__init__(name)

# 是否是黑杰克
def is_black_jack(self):
return self.cards_on_hand[0].face in [10, 11, 12, 13] and self.cards_on_hand[1].face == 1

def __str__(self):
return "【%s】点数:%d,牌面:%s" % (self._name, self.black_jack_total(), self.cards_on_hand)


def get_key(card):
return card.suite, card.face


def main():
p = Poker()
# print(p.cards)
banker = Banker('庄家')
# 电脑玩家
com_players = [Black_Jack_Player('东邪'), Black_Jack_Player('西毒'), Black_Jack_Player('南帝'),
Black_Jack_Player('北丐')]
player = Black_Jack_Player('玩家')
while True:
# 洗牌
p.shuffle()
# 下注
for com_player in com_players:
com_player.bet = random.randint(1, com_player.money)
print("【{}】下注:{}".format(com_player.name, com_player.bet))
print('玩家当前筹码:{}'.format(player.money))

ok = False
while not ok:
try:
player.bet = int(input("玩家请下注:"))
if player.bet > player.money:
raise ValueError
ok = True
except ValueError:
# 下注异常
print('输入有误')
ok = False
for i in range(2):
# 庄家拿牌
banker.get(p.next)
# 玩家拿牌
player.get(p.next)
print('玩家拿牌:{}'.format(player.cards_on_hand[i]))
# 电脑拿牌
for com_player in com_players:
com_player.get(p.next)
# 本轮是否结束标志
END = False
# 庄家明牌
print("庄家明牌为:{}".format(banker.open_hand(0)))
if banker.is_black_jack():
print("\n庄家有Black Jack:{}".format(banker.cards_on_hand))
# 庄家停牌
banker.stand = True
# 直接结算筹码,结束本轮
END = True
# 玩家轮流拿牌/停牌
while not END:
for com_player in com_players:
# 如果电脑玩家没停牌和爆掉则拿牌
# print('抽牌前:{}, stand:{}, bust:{}'.format(com_player.name, com_player.stand, com_player.bust))
if not com_player.stand and not com_player.bust:
if com_player.is_stand():
com_player.stand = True
print("【{}】:\"停牌!\"".format(com_player.name))
else:
# 局势不错选择翻倍
if com_player.face_total in [10, 11, 12] and com_player.money >= com_player.bet * 2:
com_player.double()
print("【{}】:\"运气不错,加倍!\"".format(com_player.name))
print("【{}】拿牌".format(com_player.name))
com_player.get(p.next)
if com_player.is_bust():
com_player.bust = True
print("【{}】爆掉!!".format(com_player.name))
# elif com_player.is_stand():
# com_player.stand = True
# print("【{}】:\"停牌!\"".format(com_player.name))
# print('抽牌后:{}, stand:{}, bust:{}'.format(com_player.name, com_player.stand, com_player.bust))
if not player.bust and not player.stand:
while True:
print("当前手牌:{},庄家明牌为:{}".format(player.cards_on_hand, banker.cards_on_hand[0]))
print("请选择:1.拿牌,2.停牌,3.加倍")
choose = int(input("选择:"))
if choose == 1 or choose == 3:
if choose == 3 and player.money >= player.bet * 2:
player.double()
elif choose == 3:
print('筹码不足,无法加倍!')
player.get(p.next)
if player.is_bust():
player.bust = True
print('庄家发牌,当前手牌:{}'.format(player.cards_on_hand))
break
elif choose == 2:
player.stand = True
break
# 投降
# elif choose == 4:
# player.surrender()
# player.stand = True
# break
else:
print("选择错误,请重新选择")
temp = 0
for com_player in com_players:

if com_player.stand or com_player.bust:
temp += 1
if temp == len(com_players) and (player.bust or player.stand):
END = True

# 庄家抽牌
while not banker.bust and not banker.stand:
banker.get(p.next)
if banker.is_bust():
banker.bust = True
elif banker.is_stand():
banker.stand = True
# 结算筹码
if banker.bust:
for com_player in com_players:
if not com_player.bust:
com_player.money += com_player.bet
else:
com_player.money -= com_player.bet
if not player.bust:
player.money += player.bet
else:
player.money -= player.bet
else:
for com_player in com_players:
if com_player.black_jack_total() > banker.black_jack_total() and not com_player.bust:
# 玩家为21点时赢得1.5倍赌注
if com_player.black_jack_total() == 21:
com_player.bet *= 1.5
com_player.money += com_player.bet
elif com_player.black_jack_total() == banker.black_jack_total() and not com_player.bust:
pass
else:
com_player.money -= com_player.bet
if player.black_jack_total() > banker.black_jack_total() and not player.bust:
# 玩家为21点时赢得1.5倍赌注
if player.black_jack_total() == 21:
player.bet *= 1.5
player.money += player.bet
elif player.black_jack_total() == banker.black_jack_total() and not player.bust:
pass
else:
player.money -= player.bet
# 结束一轮
print("=" * 45)
print(banker)
banker.clean_hand()
for com_player in com_players:
# 清空手牌
print(com_player, end='')
com_player.clean_hand()
# 筹码为零则离席
if com_player.money == 0:
com_players.remove(com_player)
print("\n【{}】倾家荡产,被保安拖走...".format(com_player.name))
print()
print(player)
player.clean_hand()
print("=" * 45)
input("本轮结束,请按回车继续")
if player.money <= 0:
break
print("筹码已用完,游戏结束!!")


if __name__ == '__main__':
main()

Java 设计模式之适配器模式

适配器模式(Adapter Pattern)是不兼容接口之间的桥梁,可以使一个类加入独立的或不兼容的接口功能。比如计算机通过适配器读取之前无法读取的TF卡;下面用Java模拟这一过程的实现;

阅读更多

CentOS7查杀nanoWath挖矿木马

前几天在查看服务器时状态时发现cpu占用率达到了103%

这个VPS主要是拿来玩玩,平时上面并没有什么大的服务再运行,不可能会占满CPU的;用shell客户端连上VPS,执行ps aux,其中一个叫nanoWatch的进程cpu占用率达到了99.5%

直接杀掉这个进程kill -9 17305,再检查进程,没发现异常

过了没几分钟,cpu占用又满了,查看进程,这个进程又出现了;

找到/tmp/nanoWatch这个文件,删掉这个文件,再杀掉进程,过了几分钟,进进程再次出现。

我怀疑是定时启动的任务, crontab -l查看cron计划任务,显示出来了两个定时任务,每5分钟和7分钟执行一次下载文件,我手动把这个文件下下来,是一个脚本

删除定时任务crontab -r,删掉文件,杀掉进程,结束了


过了两天,又出现CPU占用异常。

我之前一直是用root用户并使用20端口进行ssh连接,这是非常不安全的行为,很容易被端口扫描暴力破解密码登录服务器。简单的解决办法如下

[TOC]

修改ssh连接端口

用 root 用户进入 /etc/ssh/

1
2
3
4
cd /etc/ssh/
#用 vi 打开 sshd_config 文件
vim sshd_config
#添加端口20022(22号是默认端口,注释掉也是默认开启的),并解开22端口注释

1
2
3
4
5
6
7
8
9
#重启ssh 
systemctl restart sshd
#查看防火墙规则
firewall-cmd --permanent --list-port
#向防火墙中添加端口
firewall-cmd --zone=public --add-port=20022/tcp --permanent
reaload
#重新加载防火墙规则
firewall-cmd --reload

1
2
#查看20022端口是否添加成功
firewall-cmd --zone=public --query-port=20022/tcp

断开ssh连接,换用20022端口连接
修改/etc/ssh/sshd_config22号端口注释掉

1
2
3
4
#重启ssh
systemctl restart sshd
#查看ssh监听的端口
ss -tnlp|grep ssh

禁用root登入,使用普通用户登入

1
2
3
4
5
#先创建一个普通用户test,同时给test用户设置密码
adduser test
passwd test
#接着禁用root登录(修改sshd_config文件)
vi /etc/ssh/sshd_config

1
2
#重启ssh
Systemctl restart sshd.service

Docker启动Redis

1
2
#docker中启动redis并设置密码
docker run -d --name myredis -p 6379:6379 redis --requirepass "mypassword"

Docker安装Mysql5.7

在Docker中mysql5.7安装和设置与8.0基本一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# docker 中下载 mysql
docker pull mysql:5.7

#启动并设置root密码
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=your_password -d mysql:5.7

#进入容器
docker exec -it mysql bash

#登录mysql
mysql -u root -p
#设置root用户密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'your_password';

#添加远程登录用户
CREATE USER 'your_username'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
GRANT ALL PRIVILEGES ON *.* TO 'your_password'@'%';

Java 中使用Lambda表达式

Lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。使用Lambda表达式的重点是延迟执行deferred execution)。

语法

1
2
3
(Type param1,Type param2,Type param3) -> {
//TODO
}
  1. 参数类型可以省略,编译器可以根据上下文推导;但并不是所有类型都能推导出来,有时需要声明参数类型;
  2. 当参数只有一个时,小/圆括号可以省略;
  3. 当主体只有一条语句时,大括号可以省略;
  4. 当主体只有一条语句时,return可以省略;

实例

参考自runoob.com

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Java8Test {
public static void main(String[] args) {
Java8Test test = new Java8Test();
//函数式接口实例
//类型声明
MathOperation addition = (int a, int b) -> a + b;
//不用类型声明
MathOperation subtraction = (a, b) -> a - b;
//大括号中有返回语句
MathOperation multiplication = (a, b) -> {
return a * b;
};
//没有大括号及返回语句
MathOperation division = (int a, int b) -> a / b;

//函数式编程,将函数作为参数传入一个方法
System.out.println("10+5=" + test.operate(10, 5, addition));
System.out.println("10-5=" + test.operate(10, 5, subtraction));
System.out.println("10*b=" + test.operate(10, 5, multiplication));
System.out.println("10/5=" + test.operate(10, 5, division));

//单个参数可以省略括号
GreetingService greetingService1 = message -> System.out.println("Hello" + message);
//不省略括号
GreetingService greetingService2 = (message) -> System.out.println("Hello" + message);
greetingService1.sayMessage("World");
greetingService2.sayMessage("Lambda");
}

interface MathOperation {
int operation(int a, int b);
}

@FunctionalInterface
interface GreetingService {
void sayMessage(String message);
//void sayMessage(String name,String message);
@Override
String toString();
}

private int operate(int a, int b, MathOperation mathOperation) {
return mathOperation.operation(a, b);
}
}

​ 上面的实例中,将MathOperation接口(函数)做为参数传递给operate方法,返回的也是一个方法(函数),这在java 8 之前是无法做到的。这也是java 8的另一新特性,函数式编程;支持函数式编程的语言有很多,如Python、JavaScript等。

在java中Lambda表达式是对象,它必须依附于一类特别的对象类型——函数式接口(Functional Interface)

​ 函数式接口的定义:如果一个接口中,有且只有一个抽象的方法(Object类中的方法不包括在内),那这个接口就可以被看做是函数式接口。

​ 回到上面的实例中,MathOperation接口与GreetingService接口都是函数式接口,其中GreetingService内重写了Object类的toString方法,注解@FunctionalInterface用于声明该接口为函数式接口,如果某个接口(如MathOperation)满足函数式接口定义,编译器也会认为这是一个函数式接口;函数式接口内的方法不可以重载;

变量作用域

  1. Lambda 表达式只能引用声明为final的外层局部变量。
  2. Lambda 表达式中使用局部变量时,该局部变量可以不用声明为final,但是必须不可被后面的代码修改(即隐性的具有final的语义)。
  3. 在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
  4. 在 Lambda 表达式中使用this关键字时,是指创建这个Lambda表达式的方法的this参数。

Docker安装RabbitMq

1
2
#设置rabbit默认用户与密码
docker run -d --hostname rabbit-host --name rabbitMq -e RABBITMQ_DEFAULT_USER=username -e RABBITMQ_DEFAULT_PASS=password -p 5672:5672 -p 15672:15672 rabbitmq:3.7.3-management
1
2
#在docker中停止rabbitMq
docker stop rabbitMq

java中Map、Collection接口常用实现类源码浅析

在Java中集合是常用的数据结构,而MapCollection的实现类有很多,我们常见的有HashMapHashTableTreeMapLinkedHashMapArrayListLinkedlistVectorHashSetTreeSetLinkedHashSet

下面从源码的层面简析这些实现类的特性;

阅读更多