整理:劉妙慈(環境資訊中心實習編輯)
本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※南投搬家前需注意的眉眉角角,別等搬了再說!
※新北清潔公司,居家、辦公、裝潢細清專業服務
Nissan與BMW宣布,為共同強化各自旗下的電動車產品Nissan LEAF與BMW i3的客戶服務網,將合作在全美19州、共120處安裝雙頭快速充電樁。此舉未來可望刺激美國市場的電動車銷售量,並幫助電動車車主享有更便捷、廣泛的服務。
Nissan LEAF是目前全球總銷量最好的電動車款之一,充電樁設備分布在社區、企業公司以及Nissan的經銷門市。與BMW的合作,將可加速提升充電樁設備的數量,強化用戶使用經驗同時開拓市場。
BMW的北美電子移動經理Cliff Fietzek強調,與Nissan的合作還包含遠程行車的服務。一但電動車能提供更遠程的行駛距離,使用者就更能體驗電子移動科技的便利之處。
這項合作將以Nissan的充電樁技術與BMW的DC快充技術為基礎,每座快充充電樁都有CHAdeMO與SAE Combo雙街頭,輸出功率50kW,可適用於Nissan LEAF與BMW i3兩種車款以及其他擁有快充埠的電動車。50kW的快充設備可在20-30分鐘之內將Nissan LEAF或BMW i3的電池充到80%左右,比目前最常見的Level 2 240V 充電服務的效率更好。
Nissan與BMW的電動車充電樁服務範圍包括:加州、康乃迪克州、佛羅里達、喬治亞州、伊利諾州、印第安納州、馬里蘭州、明尼蘇達州、密蘇里州、新墨西哥州、內華達州、紐約、南北卡羅萊納州、俄亥俄州、賓州、田納西州、維吉尼亞州以及威斯康辛州。只要透過BWM i3的ConnectedDrive軟體,或者Nissan EZ-Charge智慧型手機app,就能快速找到充電站位置,電費可用Nissan EZ-Charge卡片結帳。
本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※南投搬家前需注意的眉眉角角,別等搬了再說!
※新北清潔公司,居家、辦公、裝潢細清專業服務
asm 為 gcc 中的關鍵字,asm 表達式為在 C代碼中嵌套彙編指令,該表達式只是單純的替換出彙編代碼,並不對彙編代碼的含義進行解析。
asm 表達式有兩種形式,第二種 asm-qualifiers
包含了 goto
語句。
第一種形式為常見的用法,AssemblerTemplate 和 OutputOperands 必須存在, 其中 Clobbers 存在需要 InputOperands 也出現。
asm asm-qualifiers ( AssemblerTemplate
: OutputOperands
[ : InputOperands
[ : Clobbers ] ])
asm asm-qualifiers ( AssemblerTemplate
:
: InputOperands
: Clobbers
: GotoLabels)
Qualifiers 的類型
參數
彙編指令由一個字符串給出,多條彙編指令結合在一起使用的時候,中間以 \r\t
隔開,如
asm("inc %0\n\tinc %0" : "=r"(res) : "0"(res));
/APP
# 11 "asm.c" 1
inc %rax
inc %rax
# 0 "" 2
/NO_APPs
需要轉義的字符:%
, =
, {
, }
, |
故在ATT彙編中,對寄存器進行操作的需要雙 %%, 如 inc %%rax
.
操作數之間用逗號分隔。 每個操作數具有以下格式:
[ [asmSymbolicName] ] constraint (cvariablename)
%[name]
c // res = num asm("movq %[num], %[res]" : [res] "=r"(res) : [num] "m"(num));
c // res = num asm("movq %1, %0" : "=r"(res) : "m"(num));
第一個參數為增加可讀性使用的,現在我們有代碼如下
int64_t res;
int64_t num = 1;
asm("movq %[num], %[res]" : [res] "=r"(res) : [num] "m"(num));
asm("movq %1, %0" : "=r"(res) : "m"(num));
asm("movq %1, %0" : "=m"(res) : "m"(num));
asm("movq %1, %0" : "=r"(res) : "r"(num));
// 對應的彙編代碼, 只保留asm表達式中的代碼
# 13 "asm.c" 1
movq -16(%rbp), %rax // asm-1
# 0 "" 2
/NO_APP
/APP
# 15 "asm.c" 1
movq -16(%rbp), %rax // asm-2
# 0 "" 2
/NO_APP
/APP
# 17 "asm.c" 1
movq -16(%rbp), -8(%rbp) // asm-3
# 0 "" 2
/NO_APP
/APP
# 19 "asm.c" 1
movq %rax, %rax // asm-4
# 0 "" 2
/NO_APP
r
為通過寄存器尋址操作,m
通過內存尋址操作,所以看到當約束了 r
就對應寄存器的操作。輸入操作數使C變量和表達式中的值可用於彙編代碼。
[ [asmSymbolicName] ] constraint (cexpression)
=
和 +
. 可以使用 “0”, 這表明在輸出約束列表中(從零開始)的條目,指定的輸入必須與輸出約束位於同一位置。int64_t res = 3;
int64_t num = 1;
asm("addq %1, %0" : "=g"(res) : "0"(num));
// 輸入輸出位置相同
movq $3, -8(%rbp)
movq $1, -16(%rbp)
movq -16(%rbp), %rax
/APP
# 32 "asm.c" 1
addq %rax, %rax
# 0 "" 2
/NO_APP
破壞列表,主要用於指示編譯器生成的彙編指令。
從asm表達式中看到輸出操作數中列出條目的更改編譯器是可以確定的,但內聯彙編代碼可能不僅對輸出進行了修改。 例如,計算可能需要其他寄存器,或者處理器可能會由於特定彙編程序指令而破壞寄存器的值。 為了將這些更改通知編譯器,在Clobber列表中列出這些會產生副作用的條目。 破壞列表條目可以是寄存器名稱,也可以是特殊的破壞列表項(在下面列出)。 每個內容列表條目都是一個字符串常量,用雙引號引起來並用逗號分隔。
寄存器
```c
asm volatile("movc3 %0, %1, %2"
: /* No outputs. */
: "r"(from), "r"(to), "g"(count)
: "%rbx", "%rcx", "%rdx", "memory");
/APP
# 25 "asm.c" 1
movc3 %rax, %r8, -72(%rbp)
# 0 "" 2
/NO_APP
```
可以看到使用到了 rax 寄存器,然後修改程序在 Clobbers 增加 %rax, 結果如下
```c
asm volatile("movc3 %0, %1, %2"
: /* No outputs. */
: "r"(from), "r"(to), "g"(count)
: "%rax", "%rbx", "%rcx", "%rdx", "memory");
/APP
# 25 "asm.c" 1
movc3 %r8, %r9, -72(%rbp)
# 0 "" 2
/NO_APP
```
編譯器在產生的彙編代碼中就未使用 %rax 寄存器了。
特殊破壞列表項
– “cc”, 表示彙編代碼修改了標誌寄存器
– “memory”, 為了確保內存中包含正確的值,編譯器可能需要在執行asm之前將特定的寄存器值刷新到內存中
編譯器為了破壞列表項的值受到破壞,當這些條目是寄存器時,不對其進行使用;為特殊參數時,重新刷新得到最新的值。
約束名 | 說明 |
---|---|
whitespace | 空白字符被忽略 |
m | 允許使用內存操作數,以及機器通常支持的任何類型的地址 |
o | 允許使用內存操作數,但前提是地址是可偏移的 |
V | 允許使用內存操作數,不可偏移的內存地址,與 “o’互斥 |
r | 允許在通用寄存器中使用的寄存器操作數,其中可以指定寄存器,如 a(%rax), b(%rbx) |
i | 允許使用立即整數操作數 |
n | 允許使用具有已知數值的立即整數操作數, ‘I’, ‘J’, ‘K’, … ‘P’ 更應該使用 n |
F | 允許使用浮點立即數 |
g | 允許使用任何寄存器,內存或立即數整數操作數,但非通用寄存器除外 |
X | 允許任何操作數, ‘0’, ‘1’, ‘2’, … ‘9’ |
p | 允許使用有效內存地址的操作數 |
標識符 | 說明 |
---|---|
= | 表示此操作數是由該指令寫入的:先前的值將被丟棄並由新數據替換 |
+ | 表示該操作數由指令讀取和寫入 |
& | 表示(在特定替代方法中)此操作數是早期指令操作數,它是在使用輸入操作數完成指令之前寫入的,故輸入操作數部分不能分配與輸出操作數相同的寄存器 |
% | 表示該操作數與後續操作數的可交換指令 |
// 避免編譯器的優化,聲明此處內存可能發生破壞
#define barrier() asm volatile("" ::: "memory")
// 在32位的CPU下,lock 指令為鎖總線,加上一條內存操作指令就達到了內存屏障的作用,64位的cpu已經有新增的 *fence 指令可以使用
// mb() 執行一個內存屏障作用的指令,為指定CPU操作;破壞列表聲明 cc memory 指示避免編譯器進行優化
#ifdef CONFIG_X86_32
#define mb() asm volatile(ALTERNATIVE("lock; addl $0,-4(%%esp)", "mfence", \
X86_FEATURE_XMM2) ::: "memory", "cc")
#define rmb() asm volatile(ALTERNATIVE("lock; addl $0,-4(%%esp)", "lfence", \
X86_FEATURE_XMM2) ::: "memory", "cc")
#define wmb() asm volatile(ALTERNATIVE("lock; addl $0,-4(%%esp)", "sfence", \
X86_FEATURE_XMM2) ::: "memory", "cc")
#else
#define mb() asm volatile("mfence":::"memory")
#define rmb() asm volatile("lfence":::"memory")
#define wmb() asm volatile("sfence" ::: "memory")
#endif
DECLARE_PER_CPU(struct task_struct *, current_task);
#define this_cpu_read_stable(var) percpu_stable_op("mov", var)
static __always_inline struct task_struct *get_current(void)
{
return this_cpu_read_stable(current_task);
}
#define percpu_stable_op(op, var) \
({ \
typeof(var) pfo_ret__; \
switch (sizeof(var)) { \
case 8: \
asm(op "q "__percpu_arg(P1)",%0" \
: "=r" (pfo_ret__) \
: "p" (&(var))); \
break; \
} \
pfo_ret__; \
})
current_task 為一個 struct task_struct 類型的指針,追蹤宏調用,在x86-64 下命中了 case 8: 的彙編代碼, 展開的代碼為
asm("mov" "q ""%%""gs" ":" "%" "P1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task)));
// 變換一下為
asm("movq %%gs:%P1, %0" : "=r"(pfo_ret__) : "p"(&(current_task)));
這行代碼的含義為將 約束輸入部分必須為有效的地址(p約束), 將CPU id(通過段寄存器gs和偏移通過GDT得到,這裏後文分析了)通過寄存器(r約束)賦值給 pfo_ret__.
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※南投搬家前需注意的眉眉角角,別等搬了再說!
※新北清潔公司,居家、辦公、裝潢細清專業服務
先來花5分鐘看完這篇文章:
看完上文,相信大家對cookie已經有了一個整體的概念,我再強調一下,cookie是一個客戶端概念,它是存儲在瀏覽器本地的一小段文本(通常由服務器來生成這段文本)。
如上文所說,cookie有許多作用,如會話狀態管理,個性化設置,瀏覽器行為跟蹤,客戶端數據的存儲等等。本篇文章就來講講基於cookie的用戶登錄狀態管理。
插一句哈,一般提到cookie,還會有一個叫session的傢伙和它一起出現,下篇文章我會講到它,以及兩者的區別。
如上圖所示,客戶端攜帶賬號和密碼向服務器發起請求,服務器在校驗通過後,通過HTTP Respose Header中的Set-Cookie頭部,將一小段文本寫入客戶端瀏覽器,在以後的每個客戶端HTTP Request Header的Cookie頭部中會自動攜帶這段文本。
下面我基於golang和gin框架(中間件使用比較舒服)來簡單的實現一個基於cookie的用戶登錄狀態管理demo
package main
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/login", Login)
// 需要登陸保護的
auth := r.Group("")
auth.Use(AuthRequired())
{
auth.GET("/me", UserInfo)
auth.GET("/logout", Logout)
}
r.Run("localhost:9000")
}
// 登陸
func Login(c *gin.Context) {
// 為了演示方便,我直接通過url明文傳遞賬號密碼,實際生產中應該用HTTP POST在body中傳遞
userID := c.Query("user_id")
password := c.Query("password")
// 用戶身份校驗(查詢數據庫)
if userID == "007" && password == "007" {
// 生成cookie
expiration := time.Now()
expiration = expiration.AddDate(0, 0, 1)
// 實際生產中我們可以加密userID
cookie := http.Cookie{Name: "userID", Value: userID, Expires: expiration}
http.SetCookie(c.Writer, &cookie)
c.JSON(http.StatusOK, gin.H{"msg": "Hello " + userID})
return
}
c.JSON(http.StatusBadRequest, gin.H{"msg": "賬號或密碼錯誤"})
}
// 檢測是否登陸的中間件
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
cookie, _ := c.Request.Cookie("userID")
if cookie == nil {
c.JSON(http.StatusUnauthorized, gin.H{"msg": "請先登陸"})
c.Abort()
}
// 實際生產中應校驗cookie是否合法
c.Next()
}
}
// 查看用戶個人信息
func UserInfo(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"msg": "007的個人頁面"})
}
// 退出登陸
func Logout(c *gin.Context) {
// 設置cookie過期
expiration := time.Now()
expiration = expiration.AddDate(0, 0, -1)
cookie := http.Cookie{Name: "userID", Value: "", Expires: expiration}
http.SetCookie(c.Writer, &cookie)
c.JSON(http.StatusOK, gin.H{"msg": "退出成功"})
}
我們來看具體的演示流程和效果:
如下圖所示,當我們退出后再去嘗試訪問個人頁面時,會出現401沒有權限的錯誤。
先來說說上面的demo存在的問題吧,我們的退出登錄函數本質是設置了一個過期了的cookie來覆蓋以前發送給用戶的正常cookie。
但是,這兒存在着一個重大的安全問題。如果用戶將之前未過期的正常cookie記錄下來(即本例子中的userID=007),即使調用了我們的logout接口,只要用戶自己手動輸入之前未過期的正常cookie,也是可以通過服務器的驗證。
而且,最重要的是,我們無法讓其失效,因為cookie的過期刪除機制是由瀏覽器來控制的,但是當用戶記錄了cookie中的哪段文本后,在cookie到期后,瀏覽器只能刪除存在於瀏覽器中的cookie,對用戶自己記錄下來的cookie確無能為力,也就是說這段cookie永遠有效。(後面我們會講一種叫json web token的技術,可以做到讓我們簽發的憑證自帶過期機制,而不依賴瀏覽器)
當然,有同學會說,我們可以在服務器存儲一份有效的cookie列表,在用戶退出登錄后,從有效列表中刪除對應的cookie,這種在服務端維護用戶狀態的機制本質是session的思想,我們後面會講基於session的用戶登錄狀態管理。
再來說說cookie別的缺點:
當然這個我們通過設置cookie的屬性為HttpOnly,來禁止JavaScript讀取cookie值,可以起到一定的防護作用。
當然,cookie也是有優點的,我們把用戶的登錄狀態保存在客戶端,這樣就不需要每一次去訪問數據庫來檢測用戶是否登錄,減少了系統的IO開銷。
本文希望通過一個不是很完美的demo來講述基於cookie的用戶登錄狀態管理,下期我們來講講session。
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※南投搬家前需注意的眉眉角角,別等搬了再說!
※新北清潔公司,居家、辦公、裝潢細清專業服務
中國京津冀等三地於7月30日簽署了協議,將共同開發京津冀區域的一體化電動汽車公共充電網絡,目標在2020年完工實施。此案將涵蓋電動車發展以及充電設備標準的設立、充電設備之量化,相關國家政策也會陸續制定提出。
中國大陸的電動車產業發展迅速,在「十二五」相關計畫之中就曾規劃2015年底要在全中國安裝40萬個電動車充電樁、2000個充換電站,但此一目標並沒有達成。究其原因,除了新能源電動車仍在發展階段之外,充電設備的標準尚未統一、社會資本進入難、營利模式單一等,都是使充電設備安裝計畫無法落實的原因。
據中國媒體《經濟參考報》指出,在京津冀三地簽署共同發展合約後,國家級的電動車充電標準文件《電動汽車充電基礎設施指南》以及《充電基礎設施指導意見》等規章也會陸續提出,這規章將具體規劃充電設備的數量:到2020年時,國內充換電站的數量目標1.2萬個,充電樁450萬個;此外,電動車與充電設施的比例也預計將從現在的4:1提升到1:1左右。在如此龐大的數量規劃下,中國充電市場的規模預計會超過人民幣1000億元。
不過,市場規模擴張的前提仍是充電設施建設能如期推行,而充電設施之建設推行則仰賴技術標準化,例如充電插槽、通訊協議等,以確保不同品牌的電動車都能一體適用。
而在盈利與資本進入困難等問題方面,政策保障將可為市場資本創造可靠的入口,進而加強獲利幅度。
中國國內的充電產業有越來越多國企、民企接連投入,例如青島特來電公司計畫到2015年底在全國40個城市建設7至10萬個充電設備,投資超過人民幣10億元,希望三年內能占全國市場50%以上。具有外資背景的富電科技公司也在今年一月在北京華貿中心落成中國首個核心商圈光伏智能充電站。車用充電業界也開始有創業者投入。
(照片來源:)
本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※南投搬家前需注意的眉眉角角,別等搬了再說!
※新北清潔公司,居家、辦公、裝潢細清專業服務
在互聯網新趨勢和新要求的變革推動下,測試行業也在不知不覺中發生着非常大的改變,從早些年的懵懂發展,大家摸着石頭過河,到大多高校設立軟件測試專業,再到近幾年各種測試培訓盛行。如果說早期軟件測試行業還是一個風口,隨着不斷地轉行人員以及畢業的大學生瘋狂地湧入軟件測試行業,目前軟件測試行業“缺口”已經基本飽和,最基礎的功能測試的崗位需求已經越來越少了。測試的進入門檻,也從真正零基礎,到現在的要求具備專業的計算機專業能力(包括不限於編程能力),軟件測試在企業的受重視程度,特別是互聯網行業,也從可有可無,到不可或缺。
測試行業不斷髮展,行業已經呈現出嚴重的兩極分化勢態,一邊是資深的測試大牛,屬於全棧複合型人才,但這一類行業中人員占的比例較為稀少。一是由於行業原因,代碼能力強,有架構經驗的人員一般都在開發部門;二是要求高,資深測試開發工程師不僅要精通測試相關的技能,還要會前端設計,服務端開發等等,幾乎是全棧工程師;而做程序的人員一般精通一點或是幾點的較多,從前到后全都能上的越來越少。另一邊是測試小白,即便是有些在測試行業中已經摸爬滾打了幾年,但仍然有很多測試人員還是停留在只會業務功能測試的這個階段。而針對這類型的測試從業人員,除了一些安於現狀的除外,大多數人其實都還是想好好學習,想進步的只是不知道學習方向,或者學習不得其法。
但不管是屬於哪一種,對於企業而言,想快速發展自己的業務,必須有一個強大的測試團隊來保證質量,通過一系列的質量保障手段,如引入CI,CD以及其他的手段來促進項目的快速迭代與交付。這就要求相關的測試工程師要能從多方面來考慮設計和解決問題,不僅要考慮項目的實施成本,還要考慮參与的測試,開發,產品甚至用戶等人員,同時要與公司發展的前景及方向相切合,並能很好地為之服務。提供這類能力的測試人才在公司都是較為吃香的,每年的找工作季節也就那麼幾個人會進入人才市場流通,而且很快就能找到工作,這也是每個測試人員的努力方向,只有具備了相應的價值實力,才有資格向企業要求你期望的回報。
很多同學抱怨,企業招人為什麼要求越來越高,除了學歷(本科以上),還要求年齡(35內),以及項目經驗,太難太難 。其實,企業也挺苦惱的:招幾個適合的人選太難了 ,這就是所謂的「供需關係」失調了 。大批測試從業者找不到工作,大量企業找不到適合的人選 。
而造成不匹配、供需關係失調的最核心的問題歸根到底還是聚焦於能力要求不匹配。
那麼測試人員核心技能或者說測試人員的核心競爭力到底有哪些? 測試人員應該思考這個問題、企業用人單位也應該要思考需要什麼樣的測試人員?相信大家面試求職時或多或少都會有這種感覺,企業在招聘時,要求會各種框架、各種編程語言、各種工具的使用。那在我們學會了測試技術、測試工具的使用,最後核心競爭力到底聚焦在哪些方面?
提到在軟件測試這個行業,你的核心競爭力是什麼?這是個非常有意思的話題,就像我們經常說的“團隊中的價值問題”,你經常看到測試人員自己在想,我們的價值在哪裡、是什麼?但我們很少看到軟件的開發人員或者架構師,或者運維團隊去問這樣一個問題,要去找自己的價值。這是因為測試人員對這個價值本身是不太確定的,那麼這個價值本身不確定,就會帶來的一系列的問題。
在早期軟件行業中,會發現存在一個普遍的現象,有些大學的本科,或者研究生畢業,他們去面試工作的時候就會發現,面試下來的是代碼能力可能不是太好,這種情況下公司會問你願不願意去做測試?但隨着現在這個時代的變革,現在的軟件測試工程師,他的知識面,以及他需要掌握的內容已經遠遠超過了之前,可以說他的知識面是遠遠超過開發的,比如在一些技術的面上,以及對產品的理解上。
那麼這種情況下,我們再去提一個優秀的軟件測試工程師的核心價值,我們可以很自信地說,測試工程師是一個不可被替代的,並且是一個專業細分化的領域。像早年的時候,我們談到測試,就是軟件測試,沒有細分市場,但現在你去談測試,測試現在的領域太多了,除了傳統意義上的,基於業務領域的測試,然後還有測試開發。
經常會有從業者諮詢我:“怎麼轉行到測試開發崗位?測試開發崗位怎麼入手?測試開發崗位到底是做什麼的?需要掌握哪些知識 ?”
其實啊,問這些問題的時候,你可能就不太適合此崗位。或者你只是聽說測試開發工資高、奔着薪資來的,也許你完全不適合 。
正如在之前介紹測試開發的文章 : 中提到過隨着現在測試開發崗在各個公司的設定,且測試開發崗一般會頂着“薪資高”的頭銜(至少在測試這個領域,測試開發的薪資普遍都要比業務手工測試高上許多),越來越多的手工測試人員,都急於想轉崗到測試開發,但需不知往往只是看到了測試開發崗的薪資高,但卻忽略了最重要的一點(那些拿高薪的人付出的努力同樣也是比你多)!我們不妨先看看下面幾則同行人的心聲。(是否曾及何時,正在讀文的你也是這麼認為的?)
之所以行業中會有許多從業人員有上述幾點心聲,最核心的問題點還是認為自己工作乾的活所得到的薪資待遇和自己希望得到的回報無法相匹配上。正如馬雲之前說過,企業員工離職的原因,歸根結底只有兩個:1、錢沒給夠。2、平台無法施展才能,覺得委屈了。
我相信絕大多數人,都是“倒”在了第一點原因上。那為什麼企業開的薪資就總是無法達到“大多數從業人員”的要求呢?難道企業開不起薪資?但身在同一個公司,為何又存在其它崗位“測試開發”、“開發”薪資高這一說法?這顯然並不是企業開不起薪資,而是企業認為TA所能幫助企業帶來的價值只值這麼多。
不論是“測試開發”或者是“開發”,頂着“薪資高”這一普遍說法,其中大多數對這個說法還是存在誤解的,並不是所謂的“崗位薪資論”,認為做了這個崗位,就一定有高的薪資,試想一下,同樣有很多開發人員,薪資不見的就比測試牛人高。而那些之所以有着“高薪崗位的人”,是因為他們所具備的能力以及能為公司帶來的價值也是越高的。因此,`高薪!= 崗位`,而**應該是高薪要等於與之匹配的能力和能為企業帶來的等同價值**。
這一觀點,恰好也回應了上述所提到的,現在越來越多的手工測試人員都想轉行測試開發。但轉行到測試開發並不是關鍵,如果能力沒有轉變,只是崗位的頭銜轉變了,即便給你安排一個測試開發或開發的頭銜,但你的能力還只是在干一些不痛不癢的工作,那麼企業仍然是不可能會為你買單的。之所有測試開發有着高薪的說法,是由於現在企業對測試開發的綜合能力已經不亞於開發,他們的技術能力和解決業務問題的能力在某些方面甚至要強於開發。因此企業肯為這些人付出高薪的回報。
我想對那些想轉崗或者埋怨自己工資低的從業人員,奉切一句:轉崗不是最終目的,提升自身能力才是根本。如果你的能力足夠出眾,能你團隊、企業帶來的價值已經超出測試所需要提供的,即便只是頂着業務測試的頭銜,我相信,企業仍然肯為你付出相應的高回報。
那些想拿高薪或者是想轉崗成為測試開發的同學,需要做的應該是要不斷提升自身能力和價值點,這些價值點立足在團隊、公司無非就是兩類能力:1.綜合技術能力、2.幫助產品業務解決問題的能力。
1. 提升綜合技術能力,說到技術,第一關:開發語言(不管是Python,還是Java,真的無所謂,先搞懂一個再說) 。
先能獨立開發一套可用的東西。至於你寫的代碼高性能、高可用,先可以放放 。但至少得通過擼代碼,實現業務方需求吧 ?
很多測試同學問,到底學Python還是學Java ?半年後,你去問他學的咋樣的,他可能還在那糾結:“到底是學Python還是學Java ?”的問題,根本就沒開始學。
“學習這事,道理都懂,就是缺行動。”,雖然這句話,看起來像廢話,但事實如此。
很多時候,看着那些:“知道自己能力有問題、想學點啥東西、到處諮詢他人應該學啥、得到答案后、依然半年沒行動”的(別笑,看文章的你,也許就是)。
否則,怎麼可能會出現:在市場上,想招一些靠譜的從業者,那麼難 。看到很多公司,耗時幾個月招不到適合的人,雖然這裡有公司的原因,但求職者能力不符合,是很大一部分原因 。
行業在發展,一直守着“自己那點業務知識、測試流程、幾年前的工具”的同學,太多 。借用之前的觀點,定期出來面試聊聊,你會發現,你根本找不到合適的工作 。
如果還在糾結學啥開發語言的,別糾結,此刻、現在,開始,學Python 。
Python易入手,簡單,好用 。而且,如果不做測試開發,通過Python也可以玩轉各種自動化測試。
OK ,如上內容,是對測試(開發)工程師核心競爭力的一些看法,摘自本人公眾號中的一部分篇幅內容,僅代表個人觀點 。
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※南投搬家前需注意的眉眉角角,別等搬了再說!
摘錄自2019年12月20日公視報導
市面上看到粉紅色的玫瑰鹽,被看作是高級的調味料。這些玫瑰鹽大多數是巴基斯坦來的,長期被印度用較便宜的價格收購來加工之後,再用較貴的價格賣出去大賺一筆。不過現在兩國關係緊張,巴基斯坦決定這錢要自己賺。
巴基斯坦北部是喜馬拉雅山脈的餘脈,首都伊斯蘭瑪巴德以南約160公里處,有一處著名的鹽嶺山脈,市面上所看到的玫瑰鹽,大部分都來自這裡山底下的凱沃拉鹽礦。
這個鹽礦長約40公里,地下17層樓深,是世界第二大鹽礦,西元326年前被發現,後來到1872年英國殖民時期,才開始發展鹽礦內設施,進行開採,2011年開放一公里的觀光區域,美麗的玫瑰色每年吸引25萬遊客前來觀光。遊客說:「我不知道岩鹽能如此美麗,我以為地底下會蠻冷的,但他們說鹽礦裡的溫度是攝氏18度。」
不過,開採方式從19世紀到現在都沒變,仍是用人工爆破的方式,危險又沒效率。
這裡每年開採的玫瑰鹽原料,大部分都以低價出口到印度跟中國,每年出口量約40萬噸,獲利卻低於5千萬美金。巴基斯坦官員表示,利潤都被印度拿走了,印度把玫瑰鹽加工後,出口到歐美各國,最近幾個月來,幾千名用戶在推特上推文,說印度賣到歐美各國的玫瑰鹽,不旦價格昂貴,而且沒有標明產地,呼籲巴基斯坦政府,保護國家的珍貴資源。
印巴暫停雙邊貿易後,不少巴基斯坦出口商,開始購買機器,自己切割加工,製成鹽燈等不同產品,賣到世界各地,希望玫瑰鹽能代表巴基斯坦,成為巴基斯坦之光。
本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※南投搬家前需注意的眉眉角角,別等搬了再說!
福特曾表示野馬 Mach-E 將在 2020 秋天開始組裝,但最近在福特墨西哥廠外卻出現一批電動野馬的身影,且看起來像幾乎可以交車了。一起來先睹為快這批電動野馬的實車英姿吧。
野馬 Mach-E(馬赫 E)是福特首輛純電車,不僅擁有全新心臟,還承繼了傳奇車款野馬的設計靈魂,因此開放預購以來業績奇佳,連一向高傲的特斯拉老闆馬斯克(Elon Musk)都發文恭喜福特,做出一台好車。
不過第一台電動車製造並沒那麼容易,因此福特將交車日期估得很晚,最快要到 2020 年底才交車,而頂規版的 Mach-E GT 更是要等到 2021 年第一季才會交車。此外,福特也說過,正式生產要到 2020 年秋天才會啟動,請大家不要太著急。
上週在墨西哥廠外出現的這批 Mach-E 卻讓大家嚇了一跳,因為看起來不僅比之前合成圖帥氣,且幾乎就像已完成組裝,而不是一般原型車或測試車。
無論原因是什麼,這台 Mach-E 是目前為止最接近實車的照片,這個造型是否打動了你的心?
今年底將交車的 Mach-E,續航里程預估有 480 公里,並擁有 332 馬力,是目前市場少數能與特斯拉並肩的數據,定價也只有 5 萬美元(台灣售價未定)。
Mach-E 售價與性能幾乎都衝著特斯拉 Model Y 而來,不過 Model Y 的交車日期可能就在未來兩個月開始,相信所有人(包括福特)都期望 Mach-E 也能提前交車,與 Model Y 一較高下。
(合作媒體:。圖片來源:)
本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※南投搬家前需注意的眉眉角角,別等搬了再說!
在閱讀這篇博客之前,希望你對SpringCloud套件熟悉和理解,更希望關注下
在使用springcloud ribbon客戶端負載均衡的時候,可以給RestTemplate bean 加一個@LoadBalanced註解,就能讓這個RestTemplate在請求時擁有客戶端負載均衡的能力,先前有細嚼過但是沒有做過筆記,剛好處理此類問題記錄下
/**
* 註釋將RestTemplate bean標記為配置為使用LoadBalancerClient。
*/
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}
通過源碼可以發現這是一個LoadBalanced
標記註解並且標記了@Qualifier
(基於Spring Boot的自動配置機制),我們可以溯源到LoadBalancerAutoConfiguration
/**
* 功能區的自動配置(客戶端負載平衡)
*/
@Configuration
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnBean(LoadBalancerClient.class)
@EnableConfigurationProperties(LoadBalancerRetryProperties.class)
public class LoadBalancerAutoConfiguration {
@LoadBalanced
@Autowired(required = false)
private List<RestTemplate> restTemplates = Collections.emptyList(); //這裏持有@LoadBalanced標記的RestTemplate實例
@Autowired(required = false)
private List<LoadBalancerRequestTransformer> transformers = Collections.emptyList();
@Bean
public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(
final ObjectProvider<List<RestTemplateCustomizer>> restTemplateCustomizers) {
return () -> restTemplateCustomizers.ifAvailable(customizers -> {
for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {
for (RestTemplateCustomizer customizer : customizers) {
//為restTemplate添加定製
customizer.customize(restTemplate);
}
}
});
}
// ...
/**
* 以下針對classpath存在RetryTemplate.class的情況配置,先忽略
*/
@Configuration
@ConditionalOnClass(RetryTemplate.class)
public static class RetryAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public LoadBalancedRetryFactory loadBalancedRetryFactory() {
return new LoadBalancedRetryFactory() {
};
}
}
// ...
}
@LoadBalanced
和@Autowried
結合使用,意思就是這裏注入的RestTempate
Bean是所有加有@LoadBalanced
註解標記的(持有@LoadBalanced
標記的RestTemplate實例)
這段自動裝配的代碼的含義不難理解,就是利用了RestTempllate的攔截器,使用RestTemplateCustomizer對所有標註了@LoadBalanced的RestTemplate Bean添加了一個LoadBalancerInterceptor攔截器,而這個攔截器的作用就是對請求的URI進行轉換獲取到具體應該請求哪個服務實例ServiceInstance。
關鍵問下自己:為什麼?
繼續扒看源碼>
上面可以看出,會LoadBalancerAutoConfiguration類
對我們加上@LoadBalanced
註解的bean 添加loadBalancerInterceptor
攔截器
/**
* 功能區的自動配置(客戶端負載平衡)。
*/
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
private LoadBalancerClient loadBalancer;
private LoadBalancerRequestFactory requestFactory;
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer,
LoadBalancerRequestFactory requestFactory) {
this.loadBalancer = loadBalancer;
this.requestFactory = requestFactory;
}
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
// for backwards compatibility
this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
}
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
Assert.state(serviceName != null,
"Request URI does not contain a valid hostname: " + originalUri);
return this.loadBalancer.execute(serviceName,
this.requestFactory.createRequest(request, body, execution));
}
}
重點看intercept方法 當我們restTemplate執行請求操作時,就會被攔截器攔截進入intercept方法,而loadBalancer是LoadBalancerClient的具體實現
public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
throws IOException {
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
Server server = getServer(loadBalancer, hint);
if (server == null) {
throw new IllegalStateException("No instances available for " + serviceId);
}
RibbonServer ribbonServer = new RibbonServer(serviceId, server,
isSecure(server, serviceId),
serverIntrospector(serviceId).getMetadata(server));
return execute(serviceId, ribbonServer, request);
}
看到這裏相信都遇到過類似的錯誤,恍然大悟
No instances available for xxxxx
這裏
注意: @LoadBalanced 標記註解獲取到最後通過負載均衡規則獲取具體的具體的server來發起請求
/**
* 服務註冊中心配置
*
* @author <a href="mailto:shangzhi.ibyte@gmail.com">iByte</a>
* @since 1.0.1
*/
@Configuration
@EnableConfigurationProperties(ModuleMappingHelper.class)
public class DiscoveryConfig {
@Autowired
Environment environment;
/**
* DiscoveryHeaderHelper默認bean
* @return
*/
@Bean
public DiscoveryHeaderHelper discoveryHeaderHelper() {
DiscoveryHeaderHelper discoveryHeaderHelper = new DiscoveryHeaderHelper(environment);
DiscoveryHeaderHelper.INSTANCE = discoveryHeaderHelper;
return discoveryHeaderHelper;
}
/**
* resttemplate構建
*/
@Resource
private RestTemplateBuilder restTemplateBuilder;
/**
* resttemplate請求bean,更改系統本身的builder
* @return
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
RestTemplate restTemplate = restTemplateBuilder.configure(new RestTemplate());
//RestTemplate interceptors 遠程調用請求增加頭部信息處理
restTemplate.getInterceptors().add(new RestApiHeaderInterceptor());
//RestTemplate Set the error handler 錯誤處理
restTemplate.setErrorHandler(new RestResponseErrorHandler());
return restTemplate;
}
@Bean
public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() {
DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs = new DiscoveryClient.DiscoveryClientOptionalArgs();
discoveryClientOptionalArgs.setAdditionalFilters(Collections.singletonList(new DiscoveryHeaderClientFilter()));
discoveryClientOptionalArgs.setEventListeners(Collections.singleton(new EurekaClientEventListener()));
return discoveryClientOptionalArgs;
}
}
源碼地址 >
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※南投搬家前需注意的眉眉角角,別等搬了再說!