【Django】RBAC權限管理系統模塊-理解

今天文章分為兩部分 :)

PART1?RBAC權限管理內容分享/?PART2 關于字節跳動一面

?

? ?

?

10 Minutes? Django-RBAC:

PART 1?

這權限管理系統主要功能是什么?

顧名思義,在系統中可以靈活的劃分角色組,可以根據功能特性來劃分:- 比如設置系統管理員角色,綁定系統所有菜單,該角色享有系統全部管理功能;- 也可以根據工作職能來劃分角色,比如設置行政管理角色,綁定流程管理功能;- 權限的劃分可以細致到 數據的瀏覽、新建、刪除、修改等操作行為 - 用戶可以關聯多個角色組,并繼承多個角色組的權限🔒

?

本文更多的是對Django的權限擴展以及如何通過擴展解決實際的業務問題展開討論,并不會對Django權限系統的具體實現和使用方法進行介紹,這方面知識未儲備好的,請先自行腦補。因為學長上周做了一套關于權限的驗證方法,感到十分痛苦,以此記錄一下相關內容,為了讓各位參考,也為社會進步。文章內容較長,各位同學請心里做好準備🐖

?

一、Django的權限系統

在介紹Django的權限系統前,我們先來認識一下RBAC。RBAC全稱Role-Based Access Control,即基于角色的訪問控制。太學術的東西就不講了,我們可以從企業運營的角度來理解RBAC,企業運營過程中,需要做很多的事情來達成企業的目標,但這些事情并非所有人都可以去做的,比如業務人員不可能去處理公司的財務問題,所以需要給要做的這些事情設置相應的權限,然后將這些權限分配給指定的人,但問題來了,如果某個員工離職了,換了一個新員工來頂替他的位置,這時你需要一一的告訴該新員工他應該做什么,他不能做什么,當工作項非常多的時候,這將是非常繁瑣的過程,且非常容易出錯,這時就引入了角色的概念,角色大家可以理解為企業管理中的崗位,通過將工作權限分配給崗位,再將員工安排至相應的工作崗位,那么該員工就擁有了該崗位應有的權限,當人員變動時,只需要將新員工安排至該崗位即可,整個過程就變得簡單多了。這時你也許會問,那崗位的工作內容變動時,你不是一樣需要重新給崗位一一分配權限嗎,增加了角色反而增加了系統的復雜性?話是沒錯,但在企業管理中,崗位是相對穩定的,而人員則是易變的,所以引入角色將極大的提升系統的靈活性和易用性。關于RBAC就簡單介紹到這,當然RBAC還包含很多的內容,希望深入了解的朋友可以Google相關的信息。?

Django的權限系統,可以認為是輕量級的RBAC系統,其中組可以對應RBAC的角色,通過將權限分配給組,再將用戶分配到組中,從而實現了授權的過程,同時Django還支持直接對用戶進行授權,這對應對一些特殊情況是十分有用的。關于Django的權限使用的詳情,可以參考官方文檔,在此不做詳述🔑

Django的權限系統實現了最基本的權限需求,但在實際的業務開發過程中,仍然存在許多無法滿足的需求,好在Django是一套異常強大的系統,系統內部提供了一套靈活的機制,使得開發人員可以方便的對系統的權限進行擴展。本文就我在實際項目過程中所遇到的各種權限方面的問題,看我如何通過擴展Django的權限系統,實現靈活的權限管理。

拿個上周的Jira說明一下,學長遇到的其實是針對不同組,來顯示不同的數據內容,我是用的DRF-去重寫get_queryset方法實現,因為我想到這個方法最為簡單,效果也十分不錯,時間就給三五天,于是我就這么干了,下面不細說我的項目,畢竟簽了商湯的保密協議~但是學長找了一個很好拓展權限的例子,比我寫的好,以此來分享給大家?

二、擴展Django的權限系統

2.1 對象級權限

在開發過程中,遇到最多的問題應該就是對象級權限的問題了。Django內置的權限授權是針對Model進行的授權,每個Model默認都會生成三個權限:add、change、delete。如一旦授予某用戶Change權限,那么該用戶就擁有了該Model所有對象的Change權限,但有些時候我們希望僅允許用戶對該Model下的指定對象進行操作。

當前學長當前這個項目內容比較亂,所有的項目數據報告都歸類到了一起,其實這么做看似簡單,后期處理十分麻煩。leader突然要讓你分開,自己組看自己組的報告...我自己做個數據的過濾,也就是上方說的重寫get_queryset方法,因為接口我用的DRF,所以修改起來也還算比較整齊。分享部分代碼供參考,就是先通過用戶判斷組別,然后在進行數據過濾篩選

所謂對象級權限,即針對的Model對象實例進行授權操作,使用我們可以精確的對單個對象進行權限的控制,以實現更細精度的權限控制。

注:此節內容主要分享了下我自己的重寫,沒有太多實質性的東西,但很多業務上的權限需求是需要結合多種權限機制實現的,在此列出是為方便后文的展開,讓各位先有個概念上的認識。其實DRF也有一套permission_class可以用的,有興趣同學也可以了解了解。

2.2 系統組的實現

什么是系統組?Django默認的權限系統中只有組的概念,沒有什么系統組啊?其實系統組只是我們為了區別與現有組的一種稱呼而已,你可以給它起一個更酷的名字。那么如何理解系統組呢?我們知道Django里的組都需要我們進行硬性的綁定才會生效的,比如你創建一個“編輯”的組,那么你需要給編輯這個組授予相應內容的編輯權限,同時你需要將相應的用戶分配至該“編輯”組,那么用戶才會真正的擁有了編輯應有的權限,這在大多數情況下是沒有問題的,但這種硬性的綁定極大的限制了系統的靈活性,因為很多時候系統是需要根據運行時的環境來決定用戶應該屬于哪些組的。結合上文對象級權限中新聞發布的例子,如果使用對象級權限的方式來實現的話,我們就必需在用戶發布新聞的同時,向對象級權限系統中添加一條權限分配的記錄(對象級權限系統是需要獨立的數據表來記錄用戶或組與對象的權限關系),這好像也沒什么問題,無非是重寫save方法或都添加一條signals就可以應對了,但如果我們希望用戶的上級領導也能夠修改該信息呢,你可能會說給上級領導也添加一條對象級權限啊,但如果該用戶的上級領導變更了呢?如果我們又希望用戶同部門的員工允許修改呢?是不是開始變得麻煩了,如果有一種機制來處理這種動態關系,那事情就變得簡單多了,而實現這一機制的就是系統組。系統組就是在系統運行期,根據運行環境來決定用戶所隸屬的組,從而實現靈活的授權機制。

看完上面的解釋,好像有點明白了,但具體該怎么實現呢?

首先,大家需要理解的一點是系統組本身并非系統運行時動態創建的,而是在開發階段根據業務需要創建的,系統組機制只是在運行時由系統決定用戶與系統組的關系而已。因而在業務開發階段,我們就必需確定好業務所需的系統組。當然我們也可以從所有的業務中抽象出一些具備全局通用性的系統組,以下列出我們抽象出來的具備通用性的系統組供大家參考:

????? 1) Everyone:所有人,無論是用戶還是訪客,都屬于Everyone組。
  2) Anonymous:匿名用戶,非認證的用戶都屬于Anonymous組。
  3) Users:用戶,所有認證的用戶都屬于Users組。
  4) Creator:創建者,針對具體信息的創建者,都屬于Creator組。
  5) Owner:所有者,具體信息的擁有者,都屬于Owner組。

?

看了上邊所列出的系統組,大家是不是感覺好像又更理解了一些呢,做過Windows文件授權的朋友,可能還有點似曾相識的感覺,對,這和Windows系統里的特殊組是一樣一樣的。除了以上所列出的系統組,我們還可以針對特定的業務創建針對性的系統組,如上例中,允許用戶的上級領導修改該用戶所發布的信息,那么我們可以創建一個名為“信息所有者的上級領導”這樣的系統組。

下面我們參考一份拓展django-admin權限的一個設計代碼:

 

# 看下面代碼,我們聲明了我們所需的系統組的常量,聲明為常量是便于代碼的調用
SYSTEM_GROUP_EVERYONE = "Everyone" # 所有人
SYSTEM_GROUP_ANONYMOUS = "Anonymous" # 匿名用戶
SYSTEM_GROUP_USERS = "Users" # 用戶
SYSTEM_GROUP_STAFFS = "Staffs" # 職員
SYSTEM_GROUP_CREATOR = "Creator" # 創建者
SYSTEM_GROUP_OWNER = "Owner" # 所有者

根據上文所述,系統組是在開發階段就應該確定!!!!否則后期像學長一樣被坑成🐕,那么確定后的系統組應該如何在系統中體現呢?其實系統組只是我們定義的一個概念,為了保證Django系統權限調用接口的一至性,它仍然是一個組對象,只是是一個我們賦予了特殊意義的組,我們仍然需要在Django的“組”這個Model中創建相應的系統組對象(當然如果考慮到系統組的特殊性,可以通過一些機制來限制對系統組的修改和刪除操作,以保證系統組始終可用,如何限制不是權限系統的核心,在此不做詳述)。你可以通過聲明一個系統組初始化的方法,并在適當的地方調用他,當然你也可以使用Django提供的初始數據方法來初始系統組。看代碼:

 

from django.contrib.auth.models import Group

?

def init_systemgroups():

"""
初始化系統組。
:return:
"""
Group.objects.get_or_create(name=SYSTEM_GROUP_EVERYONE)
Group.objects.get_or_create(name=SYSTEM_GROUP_ANONYMOUS)
Group.objects.get_or_create(name=SYSTEM_GROUP_USERS)
Group.objects.get_or_create(name=SYSTEM_GROUP_STAFFS)
Group.objects.get_or_create(name=SYSTEM_GROUP_CREATOR)
Group.objects.get_or_create(name=SYSTEM_GROUP_OWNER)

好了,現在我們已經有了系統組數據了,接下來我們就需要實現系統組的核心邏輯了,從Django所提供的權限驗證接口User.has_perm(perm, obj=None),我們可以看出存在兩種情況:

一種是不提供obj參數的情況,我們可以語義化理解為“用戶(User)是否擁有perm權限”;一種是提供了obj參數的情況,我們可以語義化理解為“用戶(User)是否擁有指定對象(obj)的perm權限”。

同樣的,我們系統組也可以分為兩種情況:一種是與obj參數無關的,我們可以語義化理解為“用戶(User)是否為系統組(system group)的成員”,這包括上面所列的Everyone、Anonymous、Users、Staffs等;一種是與obj參數有關的,我們可以語義化理解為“用戶(User)是否為對象(obj)的系統組(system group)的成員”,包括上面所列的Creator、Owner等。依賴于相同的參數,使得我們可以保持與Django一至的驗證接口,我們現在要做的是根據這些參數,給系統返回恰當的系統組,先來看看與obj參數無關的情況的代碼:

 

def get_user_systemgroups(user):
"""
獲取指定用戶所屬的系統組集合。
:param user: 指定的用戶。
:return: set 表示的用戶所屬的系統組名稱集合。
"""
groups = set()
groups.add(SYSTEM_GROUP_EVERYONE)
if user.is_anonymous():
groups.add(SYSTEM_GROUP_ANONYMOUS)
else:
groups.add(SYSTEM_GROUP_USERS)
if user.is_staff:
groups.add(SYSTEM_GROUP_STAFFS)

return groups

OK,是不是很簡單,我們只是對User進行簡單的驗證,就可以獲得User有關的系統組了,而第二種與obj參數有關的情況就比較復雜了,比如Creator組,我們必需要獲取對象的創建者,我們才能與User進行比較,從而驗證User是否為obj的創建者,然而Creator組是我們抽象出來的全局通用的組,意味著我們的Model需要提供一至的方法來獲取對象的創建者,這時我們需要定義一個接口(Python沒有提供接口的概念,我們只是通過抽象的方法來模擬)來實現:

 

class CreatorMixin(object):
"""
實現創建者的 Model 基類。
"""
def get_creator(self):
"""
獲取對象的創建者,子類重寫該方法實現創建者對象的獲取。
:return: 當前對象的創建者。
"""
return None

def set_creator(self, user):
"""
設置對象的創建者,子類重寫該方法實現創建者對象的設置。
:param creator: 要設置為創建者的User對象。
:return:
"""
pass

 

class OwnerMixin(object):
"""
實現所有者的 Model 基類。
"""
def get_owner(self):
"""
獲取對象的所有者,子類重寫該方法實現所有者對象的獲取。
:return: 當前對象的所有者。
"""
return None

def set_owner(self, user):
"""
設置對象的所有者,子類重寫該方法實現所有者對象的設置。
:param owner: 要設置為所有者的User對象。
:return:
"""
pass

現在再來看看第二種情況的實現:

 

def get_user_systemgroups_for_obj(user, obj):
"""
獲取指定用戶相對于指定的對象所屬的系統組集合。
:param user: 指定的用戶。
:param obj: 相對于指定的對象。
:return: set 表示的用戶所屬的系統組名稱集合。
"""
groups = set()
if isinstance(obj, CreatorMixin) and obj.get_creator() == user:
groups.add(SYSTEM_GROUP_CREATOR)
if isinstance(obj, OwnerMixin) and obj.get_owner() == user:
groups.add(SYSTEM_GROUP_OWNER)
return groups

現在,我們為了保證系統組的擴展性,我們需要定義一套規則,使得你可以在你自己的應用中,擴展實現自己業務所需要的系統組,我們約定在你的應用中應該存在一個模塊,模塊中應該包含有以上聲明的get_user_systemgroups(user)和get_user_systemgroups_for_obj(user, obj)兩個方法,同時你需要在項目的settings.py文件中,告訴系統你的系統組實現的模塊路徑,類似如下:

 

# 自定義系統組實現
SYSTEM_GROUP_IMPLEMENTERS = ['systemgroups.systemgroups', '你自己實現的系統組的路徑'…]

同時,我們需要提供一個方法來根據上面規則,依次獲取所有應用中的用戶所屬的系統組集合,代碼如下:

 

def get_user_systemgroups(user):
"""
從所有應用中獲取指定用戶所屬的系統組集合。
:param user: 指定的用戶。
:return: set 表示的用戶所屬的系統組名稱集合。
"""
imps = SYSTEM_GROUP_IMPLEMENTERS
groups = set()
if not imps:
return groups for imp in imps:
imp = importlib.import_module(imp)
if hasattr(imp, "get_user_systemgroups"):
groups.update(imp.get_user_systemgroups(user))
return groups

 

def get_user_systemgroups_for_obj(user, obj):
"""
從所有應用中獲取指定用戶相對于指定的對象所屬的系統組集合。
:param user: 指定的用戶。
:param obj: 相對于指定的對象。
:return: set 表示的用戶所屬的系統組名稱集合。
"""
imps = SYSTEM_GROUP_IMPLEMENTERS
groups = set()
if not imps:
return groups for imp in imps:
imp = importlib.import_module(imp)
if hasattr(imp, "get_user_systemgroups_for_obj"):
groups.update(imp.get_user_systemgroups_for_obj(user, obj))
return groups

最后,我們來實現我們的認證后端:

 

def get_group_permissions(name):
"""
獲取指定名稱的組所擁有的權限集合。
:param name: 組的名稱。
:return: 權限集合。
"""
perms = Permission.objects.filter(group__name = name)
perms = perms.values_list('content_type__app_label', 'codename').order_by()
return set(["%s.%s" % (ct, name) for ct, name in perms])def get_groups_permissions(names):
"""
獲取指定名稱的組所擁有的權限集合。
:param names: 組的名稱集合。
:return: 權限集合。
"""
perms = set()
for name in names:
perms.update(get_group_permissions(name))
return permsclass SystemGroupBackend(object):
def authenticate(self, username=None, password=None, **kwargs):
return None

def has_perm(self, user_obj, perm, obj=None):
return perm in self.get_all_permissions(user_obj, obj)

def get_all_permissions(self, user_obj, obj=None):
perms = self.get_group_permissions(user_obj, obj)
return perms def get_group_permissions(self, user_obj, obj=None):
result_perms = set()

groups = get_user_systemgroups(user_obj)
perms = get_groups_permissions(groups)
result_perms.update(perms)

if obj is None:
return result_perms

groups = get_user_systemgroups_for_obj(user_obj, obj)
perms = get_groups_permissions(groups)
result_perms.update(perms)

return result_perms

至此,我們完整的實現了系統組的機制,以上代碼因篇幅原因刪減了部分與主邏輯關系不大的代碼,如權限的緩存等,以便于閱讀和理解,完整的代碼請參考項目本著的GitHub:https://github.com/Kidwind/django-systemgroups。

2.3 權限映射

權限映射又是什么呢?要回答這個問題,我們還是以上文中的新聞發布的例子來展開,我們的新聞應該是根據性質進行分類的,比如實事新聞、財經新聞、體育新聞等等,這時我們就形成了新聞類別(InfoCategory)和新聞(Info)這兩個一對多關系的Model,隨著工作的細分,我們需要將不同的分類授權不同的部門來進行管理這時你想到的是什么?對,就是上文中所提到的對象級權限,我們給新聞類別(InfoCategory)創建一個用于控制新聞類別下的新聞的修改權限,名為change_info_by_category,通過針對新聞類別(InfoCategory)進行對象級的change_info_by_category授權,如果此時我們要進行某篇新聞的修改權限驗證,我們需要對新聞所在欄目進行change_info_by_category的權限驗證,像這樣user.has_perm(‘app_label. change_info_by_category’, obj=info.category),有什么問題嗎?似乎也沒什么問題,但我們細細分析一下,我們原本對新聞(Info)進行修改的權限驗證方法user.has_perm(‘app_label.change_info’, obj=info),需要人為的轉換為上面的權限驗證,相應的Django提供的Admin我們需要重寫相應的方法來修改權限驗證的邏輯,如果新聞(Info)本身還提供對象級的權限檢測,我們的邏輯就需要改為要對兩個方法都進行驗證,還有更多復雜的情況,情況一變,我們就需要重寫我們的權限驗證邏輯嗎,很麻煩不是嗎,如果有一種方法能夠實現上述權限驗證的自動轉換,能夠保證我們的權限調用方法不變,那事情就簡單多了,而這一方法,就是我們所說的權限映射。簡而言之,權限映射就是將用戶對當前對象所執行的權限驗證轉換為用戶對另一個對象的另一個權限進行驗證的過程

看下圖:

?

好了,分析到這里,相信大家對權限映射的作用有了大概的認識,下面我們來對代碼實現做簡單的分析和了解。同系統組一樣,我們的Model需要提供一至的方法來根據當前的權限驗證參數,獲取映射后的權限驗證參數,我們定義接口如下:

 

class PermMappableMixin(object):
"""
實現權限映射的 Model 基類。
"""
@classmethod
def mapping_permission(cls, perm, obj=None):
"""
根據當前的權限驗證參數,獲取映射后的權限驗證參數。(此類方法僅為標記方法,子類應實現相應的方法)
:param perm: 當前檢測的權限。
:param obj: 當前進行檢測權限的對象。
:return: 返回值包含兩個參數:第一個參數為映射后的權限;第二個參數為對應映射后的對象,其應為映射后權限所對應的 Model 的實例。
"""
return None, None

接下來,我們只需要實現我們的認證后端就可以了:

 

from django.contrib.contenttypes.models import ContentTypeclass PermMappingBackend(object):
def authenticate(self, username=None, password=None, **kwargs):
return None

def has_perm(self, user_obj, perm, obj=None):
app_label, codename = perm.split('.')
content_types = ContentType.objects.filter(
app_label = app_label,
permission__codename = codename) # 根據權限獲取其對應的ContentType實例。
for content_type in content_types:
model_class = content_type.model_class() # 根據 ContentType 實例獲取對應的 Model 類
if issubclass(model_class, PermMappableMixin):
mapped_perm, mapped_obj = model_class.mapping_permission(perm, obj = obj)
if mapped_perm and user_obj.has_perm(mapped_perm, obj=mapped_obj):
return True
return False

是不是很簡單,接下來看看我們新聞例子的代碼:

 

from django.utils.translation import ugettext as _from django.db import modelsclass InfoCategory(models.Model):
name = models.CharField(max_length=128, verbose_name=_('分類名稱'))

class Meta:
permissions = (
("add_info_by_category", _("允許添加分類信息")),
("change_info_by_category", _("允許修改分類信息")),
("delete_info_by_category", _("允許刪除分類信息")),
)class Info(PermMappableMixin, models.Model):
category = models.ForeignKey(InfoCategory, verbose_name=_("所屬分類"))
title = models.CharField(max_length=256, verbose_name=_('標題'))

@classmethod
def mapping_permission(cls, perm, obj=None):
mapped_perm = None
mapped_obj = None

if perm == "permmapping.add_info":
mapped_perm = "permmapping.add_info_by_category"
elif perm == "permmapping.change_info":
mapped_perm = "permmapping.change_info_by_category"
elif perm == "permmapping.delete_info":
mapped_perm = "permmapping.delete_info_by_category"

if isinstance(obj, cls):
mapped_obj = obj.category return mapped_perm, mapped_obj

三、寫在最后

Django系統提供了一套靈活的認證系統,使得我們可以通過擴展其實現靈活的權限控制策略,本文結合我在項目過程中的實踐經驗以及網絡大佬的代碼分享,為大家展示了通過對象級權限、系統組的實現、權限映射來解決項目中所遇到的幾種權限問題,同時實踐中也可以通過組合這幾種權限機制,實現更多更為復雜的權限策略。其它類的開發語言,也可以借鑒Django及上文所提到的幾種權限系統的擴展的思路,實現各自平臺的權限系統

好了,先到這里了,如果大家在實踐中有什么問題,可以給我留言,Bye~

?


?

-以上簡單描述希望對你有所幫助。共勉-

以下為分享的寶藏內容

?


?

?

我認為資料的價值在于能用、好用,不是滿足人的占有欲和獲得感。所以,也請各位擦亮雙眼,提高標準。得到的同時記得他的價值所在,收獲的同時,也請做好擇優標準。BTW,學長做的不好的地方,歡迎你們提出來,又或者如果屏幕前的你將更好的資源拿出分享,那真的十分優秀,也希望各位能無私互助。獲取資料不強制轉發。

希望學長分享的內容對你我都有幫助💪

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/455776.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/455776.shtml
英文地址,請注明出處:http://en.pswp.cn/news/455776.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

NAL的基本特征

為了保證視頻流在不同傳輸環境中能有效地傳輸,單純的高壓縮率是不夠的,必須提供有效的方法,使視頻流能夠與傳輸協議無縫連接,才能應用到各種網絡。在以前的標準中,MPEG標準包含系統層,同時制定了H&#xff…

Linux使用circos

1.在conda中安裝bioconda conda install -c bioconda circos -y # 測試是否所有的module都安裝好了 circos -module # 所有都顯示OK則成功 ok 0.39 Font::TTF::Font ok 2.68 GD ok 0.2 GD::Polyline ... .... 2.檢查模塊是否齊全 circos -module 3.下…

下一步工作的一些思考和問題

前期PL和PS部分基本開發完成了,現在開始做界面交互集成的工作,總結一些思考和問題。 1,關于software cpu的計算時間,可能會比現在長。前期實驗時是裸跑程序,加入操作系統時,由于系統的多任務,PS…

python numpy教程_Python中的Numpy入門教程

這篇文章主要介紹了 Python 中的 Numpy 入門教程,著重講解了矩陣中的數組操作 , 需要的 朋友可以參考下 1 、 Numpy 是什么 很簡單, Numpy 是 Python 的一個科學計算的庫, 提供了矩陣運算的功能, 其一般與 Scipy 、 matplotlib 一…

jquery中的 jquery.contains(a,b)

jquery.contains(a,b) 判斷元素 a中是否包含 b 元素: 源碼: contains isNative(docElem.contains) || docElem.compareDocumentPosition ?function( a, b ) {var adown a.nodeType 9 ? a.documentElement : a,bup b && b.parentNode;return a bup || !!( bup &a…

【Mysql】數據庫主從搭建-基于docker

后臺可回復【1024】即可獲取相關寶藏內容分享 :) 為什么基于Docker搭建? 資源有限 虛擬機搭建對機器配置有要求,并且安裝mysql步驟繁瑣 一臺機器上可以運行多個Docker容器 Docker容器之間相互獨立,有獨立ip,互不沖突…

塑料封裝可靠性問題淺析

塑料封裝可靠性問題淺析 摘 要: 塑料封裝器件在現在的封裝產業中具有無可比擬的優勢,諸如成本、可靠性、尺寸以及重量等.但是還是有相當一部分人對于塑封器件的可靠性持懷疑態度.文章的目的就是使讀者能夠更深入地了解到塑封器件的可靠性,尤其是在塑封器件應用于高…

java創建對象new后面為啥可以傳入參數_你有認真了解過自己的“Java對象”嗎?渣男...

對象在 JVM 中是怎么存儲的對象頭里有什么?作為一名 Javaer,生活中的我們可能暫時沒有對象,但是工作中每天都會創建大量的 Java 對象,你有試著去了解下自己的“對象”嗎?我們從四個方面重新認識下自己的“對象”創建對…

【技術+某度面經】Jenkins 內容+百度面經分享

后臺可回復【1024】即可獲取相關寶藏內容分享 :) Q1: Jenkins是什么?? A:Jenkins是一款開源 CI&CD 軟件,用于自動化各種任務,包括構建、測試和部署軟件。 今天文章分為兩部分 :) PART1 Jenkins技術分享 / PART2 關…

xcode多工程聯編 - 詳細教程

2019獨角獸企業重金招聘Python工程師標準>>> 一、創建workspace (MyProject)放入MyProject文件夾內 二、先 打開workspace 創建app1工程 點擊next之后注意選擇 workspace 同理創建app2 或者更多的工程 完成之后的工作 重新打開workspace的樣子 三、使用pod 庫 首先…

動態規劃入門 合并石子 COGS1660 石子合并

1660. 石子合并(加強版) ★★ 輸入文件:stone3.in 輸出文件:stone3.out 簡單對比時間限制:1 s 內存限制:256 MB 【題目描述】 在一個圓形操場的四周擺放N堆石子,現要將石子有次序地合并成一堆.規定…

python實現百錢買百雞

個人博客點這里 Python語言基礎(百元買百雞) 需求分析 百錢買百雞的問題算是一套非常經典的不定方程的問題,題目很簡單: 公雞5文錢一只,母雞3文錢一只,小雞3只一文錢, 用100文錢買一百只雞,其中公雞,母雞…

實數是不是python數據類型_python 基本數據類型

一、數據類型及操作 #整數類型,和數學中整數的一樣,可正可負 *十進制:210 *二進制:以0B或者0b開頭:0b1010 *八進制:以0O或者0o開頭:0o123 *十六進制:以0x或者0X開頭:0x9a…

python之用循環實現五子棋小程序

在python中我們學過流程控制中的循環結構,現在我們來進行一個小應用的練習 本程序是通過循環控制結構來實現五子棋小程序的 游戲規則 五子棋的規則如下: 對局雙方各執一色棋子。空棋盤開局。黑先、白后,交替下子,每次只能下一子。棋子下在棋盤的空白點…

Principle of Computing (Python)學習筆記(7) DFS Search + Tic Tac Toe use MiniMax Stratedy

1. Trees Tree is a recursive structure. 1.1 math nodes https://class.coursera.org/principlescomputing-001/wiki/view?pagetrees 1.2 CODE無parent域的樹 http://www.codeskulptor.org/#poc_tree.py class Tree:"""Recursive definition for tree…

C#線程篇---Task(任務)和線程池不得不說的秘密

我們要知道的是,QueueUserWorkItem這個技術存在許多限制。其中最大的問題是沒有一個內建的機制讓你知道操作在什么時候完成,也沒有一個機制在操作完成是獲得一個返回值,這些問題使得我們都不敢啟用這個技術。 Microsoft為了克服這些限制&…

關于編譯FFMPEG的初級教程

關于編譯FFMPEG的初級教程1.首先我們要下載相關工具,這里不多說,大家按照我的地址去下載文件就好了 MINGW下載地址:http://prdownloads.sourceforge.net/mingw/MinGW-3.1.0-1.exe?download 然后在下載MSYS :http://prdownloads.…

電子科學與技術相關索引匯總

電子科學與技術相關索引匯總 關于安裝deepinwindow10雙系統有時沒有聲音的問題關于deepin系統安裝design compiler的問題解答基于51單片機的交通燈控制設計基于物聯網的智能垃圾桶設計基于FPGA 的8b10b編解碼電路前端電路設計金屬磁記憶傳感器封裝集成電路版圖與工藝課程設計之…

【百度面試】閘機測試場景

面試被問到這一題思路想法: 自己找了相關內容充實自我。內容分享如下: 隨著人臉識別技術的成熟,閘機行業大量應用人臉識別算法,只因現今的人臉識別算法也已經能夠保證識別率、識別速度、誤識率和拒識率等各項指標的優異性&#x…