Skip to content

Instantly share code, notes, and snippets.

@keegoo
Last active May 27, 2024 08:44
Show Gist options
  • Save keegoo/a2bde319d4631a3fd8aaa9ac8cd14e9a to your computer and use it in GitHub Desktop.
Save keegoo/a2bde319d4631a3fd8aaa9ac8cd14e9a to your computer and use it in GitHub Desktop.

面试前浏览一遍。。。每项只维持100个

记录下接下来要了解的问题:

  • Pytest如何并行运行测试,pytest-xdist是如何实现的;
  • 由于k8s和redis的基本知识的总结;因为他们太常用到了;使用ps命令时,是否可以看到docker container里面运行的进程;
  • Kibana和watchdog这种log实现的原理是啥,如何保证速度?
  • 服务在cloud中如何被发现。

目录

Python

  1. set可以实现list去重,set([1, 2, 3, 4, 4, 5, 5]) => {1, 2, 3, 4, 5}
  2. range(100)的返回是可迭代对象,但并不是迭代器,所以next(range(100))会报错;需要先转换为迭代器才可运行it = iter(range(100)); next(it)
  3. tuple与list的区别是,tuple是immutable的。
  4. set与list的区别是,set是unique的。并且由于set的实现方式与哈希表类似,所以set也是unordered的,set(['a',1, 2, 'c']) => {1, 2, 'c', 'a'}
  5. __init__的默认返回是None,返回其他数值会报错。
  6. sorted()的key参数(function)决定了排序的方法,sorted(['abc', 'd', 'fg'], key=len) => ['d', 'fg', 'abc']
  7. list.sort()和sorted()的区别是,.sort会修改原始列表,但是sorted会返回新的列表。
  8. 展开(spread)列表,a = [1, 2, 3, 4]; b = [5, 6, *a]
  9. try..except..else没有捕捉到异常就执行else语句;try..except..finally不管是否捕捉到异常,都执行finally语句。
  10. 交换数值a, b = b, a
  11. 使用zip将位置相同的数值组织到一起,list(zip(['a', 'b', 'c'], [1, 2, 3], [10, 20, 30])) = > [('a', 1, 10), ()...]
  12. 使用zip和*将组织在一起的数值分开,mapped = list(zip(...)); zip(*mapped)
  13. list.remove()从list中移除元素,多次出现的元素只移除一个,函数更改了原列表。
  14. dict.pop()从dict中移除元素,函数更改了原字典。
  15. 0,空字符串,空列表、空字典、空元组、None, False在python中都为假。
  16. 元类(meta class)是类的类(classes' classes),允许你创建或者修改类。
  17. class Dog: bar = TrueDog = type('Dog', (), {'bar': True})是等价的。所以type()并不简单。
  18. Python的magic methods(class中以'__'开头的方法)是对应API的具体实现,所以一般情况下,尽量使用var()而不是__dict__。类似的,尽量使用len(a_list)而不是a_list.__len__(),使用a_dict["key"]而不是a_dict.__getitem__('key')
  19. 在Python中,生成器类和生成器函数有着同样的效果(如下面例子所示)。 生成器(Generator)的好处是内存使用上,它不必将整个list存储在内存中。StopIteration异常用于标识迭代的完成。但大多数时候Python会自动管理迭代是否结束,所以你并不需要手动raise StopIteration
# 生成器类
class Odds:
    def __init__(self, max):
        self.n=3
        self.max=max
    def __iter__(self):
        return self
    def __next__(self):
        if self.n <= self.max:
            result = self.n
            self.n += 2
            return result
        else:
            raise StopIteration
numbers = Odds(10)
print(next(numbers))
print(next(numbers))
print(next(numbers))

# 生成器函数
def odds_generator(max):
    n = 1
    while n < max:
      yield n
      n += 2

numbers = odds_generator(10)
print(next(numbers))
print(next(numbers))
print(next(numbers))
  1. Python Enum是个不错的枚举类型;大多数时候你并不需要访问到枚举类型的value属性。
from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

print(Color.RED)        # 输出: Color.RED
print(Color.RED.value)  # 输出: 1

# 绝大多数时候并不需要访问到value属性
if Color.RED == Color.RED:
    print("看得到此条输出1.")

class Sex(Enum):
    MALE = 1
    FEMALE = 2

# 绝大多数时候并不需要访问到value属性
if (Color.RED != Sex.MALE):
    print("看得到此条输出2.")
  1. functools是python标准库的一部分,包含很多高阶函数(在函数式编程中很流行)。例如: reduce, partial, wraps 和 cache相关的函数 等等。
  2. reduce函数体现的是一个聚合的概念,将二元函数经过多次运算聚合成一个值。对他的理解不能只停留在求和运算上。
from functools import reduce

# 求和运算
reduce(lambda x,y: x+y, [1, 2, 3, 4, 5], 0) # => 15

# 剥洋葱
reduce(lambda data, k: data[k] if data and k in data else None, ["a", "b"], {"a":{"b":"c"}}) #=> 'c'

# 穿衣服
reduce(lambda v, k: k if v is None else {k: v}, ["a", "b", "c"], None)  # => {'c': {'b': 'a'}}
  1. A context manager(上下文管理器) is an object that can be used in a with block. Context managers need a enter method and a exit method, and the exit method should accept three positional arguments(exception class, exception object and a traceback object). Python's contextlib module includes a contextmanager decorator which allows for creating context managers using a function syntax.
import os
from contextlib import contextmanager

# temporarily changes the value of an environment variable
class set_env_var:
    def __init__(self, var_name, new_value):
        self.var_name = var_name
        self.new_value = new_value

    def __enter__(self):
        self.original_value = os.environ.get(self.var_name)
        os.environ[self.var_name] = self.new_value

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.original_value is None:
            del os.environ[self.var_name]
        else:
            os.environ[self.var_name] = self.original_value

# ------ ------
# equivalent to:

@contextmanager
def set_env_var(var_name, new_value):
    original_value = os.environ.get(var_name)
    os.environ[var_name] = new_value
    try:
        yield
    finally:
        if original_value is None:
            del os.environ[var_name]
        else:
            os.environ[var_name] = original_value
            
with set_env_var("USER", "akin"):
    print("USER env var is", os.environ["USER"])
    
# Note:
# The `as` keyword will point a given variable name to the return value from the `__enter__` method.
# We don't use `as` in this example due to `__enter__` didn't return any value (returns None).
  1. Python Class中__repr__是这一对象的字符串表达。__str__也是实现类似的功能;两者的区别是: __repr__应该返回一个字符串,以便用于重建对象,即当你将这个字符串传递给eval()时,能够创建出一个与原对象相同状态的新对象,这是它的主要目的;__str__只是用于生成一个可读性更好的字符串。
  2. @property装饰器允许像访问属性一样访问方法。E.g. 像circle.radius,而不是circle.radius()
  3. 非常经典的把class用作decorator的例子。注意 1).被缓存的值是存储在每个Memoizer的实例中,而实例在fibonacci被调用时被创建,此实例被绑定在fibonacci这个变量中;2).在class中存在__call__的时候,大多数时候此对象会被用作decorator; 3).f = decorator(f)是装饰器的本质,所以fibonacci是在对象初始化时被传入的。
class Memoizer:
    def __init__(self, func):
        self.func = func
        self.memo = {}

    def __call__(self, *args):
        if args not in self.memo:
            self.memo[args] = self.func(*args)
        return self.memo[args]

@Memoizer
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

# Usage
print(fibonacci(5))
  1. %-formatting本身是immediate evaluate的。但是当和Python的logging一起使用时是lazy evaulation(应该是和logging的实现有关)。所以这段代码logging.debug("Name: %s, Age: %d" % (name, age))当logging level是INFO或更高时,%-formatting并不会被执行。

Development

  1. Git rebase helps to maintain a linear project history. Firstly git checkout <branch name>, then on that perticular branch, execute git rebase <base>. Usually after a rebase, a --force push is needed.
  2. 删除remote上的一个branch,git push origin -d remote-branch-name.

装修

最近在装修,记录下学习到的知识。

  1. 螺丝钉的规格一般标注为 M4*20, M6*20。其中4(或6)代表螺纹部分的直径,20代表螺丝钉的长度(不含头部),都是以毫米为单位。下图来自我常买的淘宝店,解释的很详细。 image

  2. 膨胀管是用来在水泥墙上固定螺丝钉的,它的型号一般标注为 6*20, 8*20。其中6(或8)代表管子的外直径(或者钻孔的直径),20代表管子的长度。下图也是来自同一家淘宝店。注意在搭配螺丝钉时,长度要一致,但是螺丝钉的直径要小一些。 image

  3. 在固定宜家洞洞板这类比较轻的东西时,6*30的膨胀管 + M4*30的螺丝钉就够了。

  4. 我在拆家里的壁橱时(3开门的壁橱,比较大;买房自带的),发现用的是 10*60的膨胀管 + M6*60的螺丝钉。也非常的稳固。

乱七八糟

  1. 林毅夫解读2022政府中作报告的视频中提到

从要素禀赋结构里面来看就很清楚,在收入水平低的时候为什么工资低啊,因为劳动供给相对丰富,资源相对不足。当你资本积累非常快,资本就会逐渐从相对短缺变成相对丰富。反过来讲,劳动力就会从相对丰富变成相对短缺。在这种要素禀赋结构的变化的状况之下,工资会上涨的非常的快。

  1. 酷玩实验室Hugo介绍关于使用不锈钢材料替代铝材料的行业趋势,和金为新材GNT这家企业。关于钢和铝,简单总结就是铝制品的制作工艺简单,但是对环境污染很大,同时价格很贵;钢制品主要是制作工艺要求高,但是对环境影响很小,成本也很低,即便在轻量化上还不如铝,但是应用前景广阔。金为新材GNT这家企业使用冷流变技术(有自主知识产权),突破了钢制品工艺上的限制,打破了德国和瑞士的技术枷锁。目前还被应用到中国探月工程,高铁,光伏面板等新兴领域。而且查看这家企业的官网,创业故事和企业愿景也非常令人振奋,值得关注。

  2. 魏南枝(中国社会科学院)在全球化调整期与中国的战略新机遇期(四)视频中的提问,关于生产者国家和消费者国家的论述。

美国它在20世纪的下半叶,已经从一个生产者国家变为一个消费者国家,这个在您的报告里面讲的非常的精彩:分析这个变化,包括它现在这种生产能力会成为他的一个最大的短板。包括现在大家都在说,台积电要搬到美国去等等。但是我个人的观点就是说实际上搬过去会怎么样,会打一个大大的问号。因为它整个生产者这一块,它的短板是非常凸显的。因为它从一个生产国家变成一个消费者的国家用了几十年,想变回来不是那么容易的。在已经变为消费者国家以后,这种购买者的理念压倒了公民理念。购买者肯定会有能力的差异和购买的喜好的差异,就会使得它整个社会的碎片化,缺乏共同价值。然后不同的社区、不同的城市、不同的职业等等,它的这种理念压倒了公民理念之后,美国的共同价值观和共同的向心力还在吗?它还有可能从消费者国家变回到生产者国家吗?

  1. 翟东升在全球化调整期与中国的战略新机遇期(四)视频中关于GDP误导性的论述。

GDP是带有误导性的...GDP把可贸易品和不可贸易品混为一谈。不可贸易品,比如理发在华盛顿郊区是30多美元...在北京郊区是30多人民币,在河内郊区可能是3块人民币...同样的劳动甚至河内理的最好,它(不可贸易品)不具有一价定律,所以我们应该把不可贸易部分的经济统计看作是一个财富再分配过程。然后我们把财富创造的过程单独统计起来...这样才能看清楚真实世界的经济活动重心在哪里,它的真正的实力对比在哪里。从这个角度看我们远大于美国。

  1. 黄江南教授关于债务的存款发行和贷款发行的论述,简单来说就是:美国可以印钱发债,因为发出去的钱可以立即转换为商品;而中国在改革开放早期,因为印出来的钱不能直接转换为商品,所以会带来通胀,所以只能基于存款发放贷款。 美国资本是否能与中国市场脱钩?(上)

中国已经经过一个发展阶段,从存款发行转为了贷款发行。存款发行就是没有存款你就没法贷款。特别是在工业社会的早期和初期,还在短缺经济的情况下,他一定是存款发行。当国家的生产力发展到一定程度,在各行各业都有剩余产能的情况下,社会就变成了贷款发行。到了贷款发行的情况下,资本就没有界限。资本就要钱嘛,以前存款发行说好,你要钱,但是没有存款就没有贷款,没钱。如果没钱也贷就会发生通货膨胀。在富足经济下有了丰富的产能,你只要贷款,当钱拿出去花的时候,就会有产品给你提供。没有产品也能立即生产因为有富余产能。这就是贷款发行理论。

  1. youtube上关于电源线国际标准的介绍,比如最常用的C13/C14。帮助了解220V电源线。 Power Connector - Overview

物联网

  1. 低功耗蓝牙(Bluetooth Low Energy, BLE)。早在Bluetooth 4.2时代(December 2, 2014),低功耗蓝牙就成为了规范的一部分。但是它只是规范的可选项,所以当你购买了传统的蓝牙(比如5.0)设备,并不一定说明此设备就是支持低功耗(BLE)的。
  2. 双模蓝牙(Dual-Mode Bluetooth)就是指设备即支持传统蓝牙(Bluetooth Classic)又支持低功耗蓝牙(Bluetooth BLE)。传统蓝牙和低功耗蓝牙之间并没有谁兼容谁的概念,而是两者工作在不同的模式下。一般IoT设备考虑到电量消耗,都只支持低功耗蓝牙。而像手机,笔记本,网关等设备电量比较充足,都是支持双模蓝牙的。
  3. 传统蓝牙设备间的通信是星型拓扑结构,即一个Central同时连接多个Peripheral。而蓝牙组网(Bluetooth Mesh)是基于低功耗蓝牙开发的组网协议,实现多对多的设备间通信。他不是简单的Bluetooth 5.0的升级,而是独立于蓝牙协议之外的一套协议。
  4. Zigbee具有mesh功能,所以在对比时,一般拿Zigbee和Bluetooth Mesh(蓝牙组网)来对比。这里要说明一点Zigbee是不需要授权费的(license-free)。
  5. Zigbee和Bluetooth Mesh都不具有IP地址,所以都需要通过各自的网关来进行控制。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment