<dfn id="hx5t3"><strike id="hx5t3"><em id="hx5t3"></em></strike></dfn>

    <thead id="hx5t3"></thead><nobr id="hx5t3"><font id="hx5t3"><rp id="hx5t3"></rp></font></nobr>

    <listing id="hx5t3"></listing>

    <var id="hx5t3"></var>
    <big id="hx5t3"></big>

      
      

      <output id="hx5t3"><ruby id="hx5t3"></ruby></output>
      <menuitem id="hx5t3"><dfn id="hx5t3"></dfn></menuitem>

      <big id="hx5t3"></big>

        依云

        依云 查看完整檔案

        北京編輯  |  填寫畢業院校  |  填寫所在公司/組織 blog.lilydjwg.me/ 編輯
        編輯

        即日起我不在此查看可以回答的問題。

        在這里,我遇到了一些問題,比如亂打標簽,比如解決了不標記為解決,甚至言語攻擊。時間不應該浪費在這些不尊重回答者的用戶上。

        想要我幫忙解決技術問題,可以向我付費提問: http://www.tvxinternet.com/pay/...

        個人動態

        依云 贊了文章 · 2020-05-23

        [譯] C程序員該知道的內存知識 (4)

        系列更新:

        這是本系列的第4篇,也是最后一篇,含淚填完這個坑不容易,感謝閱讀~

        這個系列太干了,閱讀量一篇比一篇少,但我仍然認為這個系列非常有價值,在翻譯的過程中我也借機進行系統性的梳理、并學習了很多新知識,收獲滿滿。希望你也能有收獲(但肯定沒我多)。

        那,開始吧。


        理解內存消耗

        工具箱:

        • vmtouch[2] -?portable virtual memory toucher

        (譯注:vmtouch這個工具用來診斷和控制系統對文件系統的緩存,例如查看某個文件被緩存了多少頁,清空某個文件的緩存頁,或將某個文件的頁面鎖定在內存中;基于這些功能可以實現很多有意思的應用;詳情參考該工具的文檔。)

        然而共享內存的概念導致傳統方案 —— 測量對內存的占用 —— 變得無效了,因為沒有一個公正的方法可以測量你進程的獨占空間。這會引起困惑甚至恐懼,可能是兩方面的:

        用上了基于 mmap?的I/O操作后,我們的應用現在幾乎不占用內存.

        —?CorporateGuy

        求救!我這寫入共享內存的進程有嚴重的內存泄漏?。?!

        —?HeavyLifter666

        頁面有兩種狀態:清潔(clean)頁和臟(dirty)頁。區別是,臟頁在被回收之前需要被寫回到持久存儲中(譯注:寫回文件實際存放的地方)。MADV_FREE 這個建議通過將臟標志位清零這種方式來實現更輕量的內存釋放,而不是修改整個頁表項(譯注:page table entry,??s寫為PTE,記錄頁面的物理頁號及若干標志位,如能否讀寫、是否臟頁、是否在內存中等)。此外,每一頁都可能是私有的或共享的,這正是導致困惑的源頭。

        前面引用的兩個都是(部分)真實的,取決于視角。在系統緩沖區的頁面需要計入進程的內存消耗里嗎?如果進程修改了緩沖區里那些映射文件的那些頁面呢?在這混亂中可以整出點有用的東西么?

        假設有一個進程,索倫之眼(the_eye) 會寫入對魔都(mordor)的共享映射(譯注:指環王的梗)。寫入共享內存不計入 RSS(resident set size,常駐內存集)的,對吧?

        $ ps -p $$ -o pid,rss
          PID  RSS
        17906  1574944 # <-- 什么鬼? 占用1.5GB?

        (譯注:$$ 是 bash 變量,保存了在執行當前script的shell的PID;這里應該是用來指代the_eye的PID)

        呃,讓我們回到小黑板。

        PSS(Proportional Set Size)

        PSS(譯注:Proportional 意思是 “比例的”) 計入了私有映射,以及按比例計入共享映射。這是我們能得到的最合理的內存計算方式了。關于“比例”,是指將共享內存除以共享它的進程數量。舉個例子,有個應用需要讀寫某個共享內存映射:

        $ cat /proc/$$/maps
        00400000-00410000         r-xp 0000 08:03 1442958 /tmp/the_eye
        00bda000-01a3a000         rw-p 0000 00:00 0       [heap]
        7efd09d68000-7f0509d68000 rw-s 0000 08:03 4065561 /tmp/mordor.map
        7f0509f69000-7f050a108000 r-xp 0000 08:03 2490410 libc-2.19.so
        7fffdc9df000-7fffdca00000 rw-p 0000 00:00 0       [stack]
        ... 以下截斷 ...

        (譯注:cat /proc/$PID/maps 是從內核中讀取進程的所有內存映射)

        這是個被簡化并截斷了的映射,第一列是地址范圍,第二列是權限信息,其中 r 表示可讀, w 表示可寫,x 表示可執行 ——?這都是老知識點了 —— 然后 s 表示共享,p 表示私有。然后是映射文件的偏移量,設備號(OS分配的),inode號(文件系統上的),以及最后是文件的路徑名。具體參見這個文檔[3](譯注:kernel.org 對 /proc 文件系統的說明文檔),超級詳細。

        我得承認我刪掉了一些輸出中一些不太有意思的信息。如果你對被私有映射的庫感興趣的話可以讀一下 FAQ-為什么“strict overcommit”是個蠢主意[4](譯注:根據這個FAQ,strict overcommit應該是指允許overcommmit、但要為申請的每一個虛擬頁分配一個真實頁,不管是用物理頁還是swap,確實聽起來很蠢……)。不過這里我們感興趣的是魔都(mordor)這個映射:

        $ grep -A12 mordor.map /proc/$$/smaps
        Size:           33554432 kB
        Rss:             1557632 kB
        Pss:             1557632 kB
        Shared_Clean:          0 kB
        Shared_Dirty:          0 kB
        Private_Clean:   1557632 kB
        Private_Dirty:         0 kB
        Referenced:      1557632 kB
        Anonymous:             0 kB
        AnonHugePages:         0 kB
        Swap:                  0 kB
        KernelPageSize:        4 kB
        MMUPageSize:           4 kB
        Locked:                0 kB
        VmFlags: rd wr sh mr mw me ms sd

        譯注:這個文件大小 32GB,已加載了 1521MB 到內存中,因為只有這一個進程映射了它,所以在這個進程的PSS中占比是100%,也是 1521MB。

        在共享映射里的私有頁面 —— 搞得我像巫師一樣?在Linux上,即使共享內存也會被認為是私有的,除非它真的被共享了(譯注:不止一個進程創建共享映射)。讓我們看看它是否在系統緩沖區里:

        #?好像開頭的那一塊在內存中...
        $ vmtouch -m 64G -v mordor.map
        [OOo                    ] 389440/8388608
        
                   Files: 1
             Directories: 0
          Resident Pages: 389440/8388608  1G/32G  4.64%
                 Elapsed: 0.27624 seconds
        
        # 將它全都載入到Cache!
        $ cat mordor.map > /dev/null
        $ vmtouch -m 64G -v mordor.map
        [ooooooooo      oooOOOOO] 2919606/8388608
        
                   Files: 1
             Directories: 0
          Resident Pages: 2919606/8388608  11G/32G  34.8%
                 Elapsed: 0.59845 seconds

        譯注:

        1. “-m 64G”?表示允許 vmtouch 將小于 64G 的文件加載到內存中,應當是用于需要加載一個目錄下的文件、但排除其中過大的文件,似乎不適用于這里;至少忽略這個參數不影響閱讀
        2. o 表示這一塊部分被加載,O 表示全部被加載。因為物理內存有限,雖然全量讀取了文件,但只有部分內容被緩存

        嗬,只是簡單地讀取一個文件就會把它緩存起來?先不管這,我們的進程呢?

        $ ps?-p?$$?-o?pid,rss
          PID   RSS
        17906 286584 # <-- 等了足足一分鐘

        常見的誤解是,映射文件會消耗內存,而通過文件API讀取不會。實際上,無論哪一種方式,包含文件內容的頁面都會被放進系統緩沖區。但還有個小的區別是,使用mmap的方式需要在進程的頁表中創建對應的頁表項(PTE),而這些包含文件內容的頁面是可以被共享的。有趣的是,我們這個進程的RSS縮小了,因為系統?_需要_ 進程的頁面了(譯注:因為 mordor 太大,可用物理內存頁不夠,系統將 the_eye 的部分頁面swap了;所以前述命令才會需要等一分鐘,因為涉及到磁盤IO)。

        有時我們的所有想法都是錯的

        映射文件的內存總是可被回收的,區別只在于該頁是否臟頁 —— 臟頁在回收前需要被清理(譯注:寫回底層存儲)。所以當你在 top 命令發現有一個進程占用了大量內存時是否需要恐慌?當這個進程有很多匿名的臟頁的時候才需要恐慌——因為這些頁面無法被回收。如果你發現有個匿名映射段在增長,你可能就有麻煩了(而且是雙倍的麻煩)。但是不要盲目相信 RSS 甚至 PSS 。

        另一個常見錯誤是認為進程的虛擬內存和實際消耗內存之間總有某種關系,甚至認為所有內存映射都一樣。任何可回收的內存,實際上都可以認為是空閑的。簡而言之,它不會導致你下次內存分配失敗,但_可能_會增加分配的延遲 ——?這點我會解釋:

        內存管理器需要花很大功夫來決定哪些東西需要保存在物理內存里。它可能會決定將進程內存中的一部分調到swap,以便給系統緩存騰出空間,因此該進程下次訪問這一塊時需要再將這些頁面調回到物理內存中。幸運的是這通常是可以配置的。例如,Linux 有一個叫做 swappiness[5] 的選項,用來指導內核何時開始將匿名映射的內存頁調出到swap。當它取值為 0 是表示“直到絕對絕對有必要的時候”(譯注:取值[0, 100],值越低,系統越傾向于先清理系統緩沖區的頁面)。

        終章,一勞永逸地

        如果你看到這里,向你致敬!我在工作之余寫的這篇文章,希望能用一種更方便的方式,不僅能解釋這些說過上千遍的概念,還能幫我整理這些思維,以及幫助其他人。我花了比預期更長的時間。遠超預期。

        我對文章的作者們只有無盡的敬意,因為寫作真是個冗長乏味、令人頭禿的過程,需要永無止境的修改和重寫。Jeff Atwood(譯注:stack overflow的創始人)曾說過,最好的學編程書籍是教你蓋房子的那本。我不記得在哪兒了,所以無法引用它。我只能說,第二好的是教你寫作的那本。說到底,編程本質上就是寫故事,簡明扼要。

        EDIT:我修正了關于 alloca() 和 將 sizeof(char) 誤寫為 sizeof(char*) 的錯誤,多虧了 immibis 和 BonzaiThePenguin。感謝 sWvich 指出在 slab + sizeof(struct slab)?里漏了的類型轉換。顯然我應該用靜態分析跑一下這篇文章,但并沒有 ——?漲經驗了。

        開放問題 —— 有沒有比 Markdown 代碼塊更好的實現?我希望能展示帶注釋的摘錄,并且能下載整個代碼塊。

        寫于 2015 年 2 月 20 日。



        讀到這里都是真愛,喜歡的話請點贊,感謝~

        照例再貼下之前推送的幾篇文章:

        歡迎關注

        weixin1.png


        參考鏈接:

        [1]?What a C programmer should know about memory

        [2] vmtouch - the Virtual Memory Toucher

        [3] kernel.org - THE?/proc FILESYSTEM

        [4] FAQ (Why is “strict overcommit” a dumb idea?)

        [5] wikipedia -?Paging -?swapinness

        查看原文

        贊 13 收藏 7 評論 0

        依云 贊了文章 · 2020-01-28

        Fedora,從安裝到放棄

        550+ RMB 買了個筆記本——聯想 T61,翻新的,雜湊的……甭問從哪買的,我不是托。

        擱小十年前,我很窮的時候,它對我來說是高端本,只有在網上看看的份。非常不幸,小十年后,我依然很窮,所以 550+ RMB 買了個雜湊的,翻新的……網店老板給它預裝了雨林木風 Win XP。

        一直都覺得,XP 是最經典的 Windows 系統。Windows 7 是為了填 Vista 的坑。Windows 10,則讓諸位變成了微軟茍延殘喘的戰略的炮灰。不過,XP 如日中天的時候,我為了搶占所謂的道德制高點,義無反顧的擁抱了 Linux。

        我正式用的第一個 Linux 發行版是 Fedora Core 4。老 Linux 用戶知道的,Fedora Core 是 RedHat 的繼承者,也是 Fedora 的前身。往事不堪回首,唏噓一番之后,決定安裝最新的 Fedora 24,像一名 Linux 新手那樣……

        來玩一個安裝 Fedora 的游戲吧!

        LiveUSB

        https://getfedora.org 網站下載了 Workstation 版本的光盤鏡象文件,然后在 Windows 系統中使用 Fedora 項目提供的 liveusb-creator 工具將光盤鏡象文件『刻錄』到我的 2GB 的 U 盤上。

        將 U 盤插到本上,摁下開機鍵,ThinkPad 開機畫面出現的那一瞬間,快速摁下 F12 鍵,進入啟動介質選單,選擇了 U 盤啟動,回車……于是就遇到第一只怪獸:

        vesamenu.c32: not a COM32R image
        boot:

        嚇死本本了……google 的結果顯示,這只怪獸很古老了,2010 年就出現了。傳說,bug 們,如果很長時間沒有被修復,它們取天地之靈氣,吸日月之精華,久而久之就成精了,就成 feature 了。

        對付這只怪獸的招數是,輸入咒語『linux』,然后回車,喝杯茶的功夫就進入了 Fedora 的 Live 系統??赡芮皟赡?,這句咒語是『linux0』,我試過了,不靈。今年,需要去掉 0。

        后來,我在 Gentoo 系統中,按照 Fedora 官方介紹的姿勢,用 dd 命令將光盤鏡象文件刻錄到 U 盤上:

        $ sudo dd if=Fedora-Workstation-Live-x86_64-24-1.2.iso of=/dev/sdb

        這樣做,vesamenu.c32 怪獸就不會再出現,很順利的進入 Fedora Live 系統……不過,這只是安徒生童話里才有的結局。實際上,dd 命令,我嘗試了三次才成功。第一次失敗,可能是因為我的 U 盤已經被 liveusb-creator 工具寫入了一些數據,導致它的分區不再是 FAT32 格式。第二次失敗,是因為我錯誤的選擇了 Linux 分區格式,然后又用 mkfs.vfat 命令將其格式化為 FAT32 格式。第三次,是分區時選了 FAT32 格式,然后用 mkfs.vfat 格式化為 FAT32 格式……成功了!

        進入 Fedora Live 系統(實際上是 GNOME 3 桌面)之后,找到『Install to Hard Drive』按鈕,便可進入安裝 Fedora 的過程。

        分區

        安裝 Fedora 的過程中,大 BOSS 是硬盤的分區。我只需要機器上有個單系統,所以這個大 BOSS,我打起來不怎么費力。更何況,我這機器是小十年前的,根本不需要考慮 UEFI 之類雜七雜八的問題。

        硬盤一共 80GB 空間,分了 1 GB 給 /boot,40 GB 給 /,4 GB 給了 swap,剩下的給了 /home。

        我想對身為 Windows 高手的 Linux 小白解釋一下,/boot 類似于 C 盤,/ 類似于 D 盤,/home 類似于 E 盤,swap 就是 pagefile.sys 文件。之所以不像 Windows 那樣簡單明快,是因為 Linux 繼承了 Unix 的一切皆文件的哲學。文件系統是一個樹狀結構,/ 是文件系統的根結點,/boot/home 是第二層結點。不過,這種樹形關系是邏輯上的,對硬盤進行分區,就是將文件系統中的部分結點綁定到硬盤分區。swap 分區不在文件系統中,它是隱匿的分區……Windows 的 pagefile.sys 默認也是隱藏起來的。

        裝好 Fedora 之后要做的第一件事

        網上有一些文章,標題是『裝好 Fedora 之后要做的 x 件事』,其中第一件事大都是『更新系統』。這是錯誤的做法。正確的做法是,刪除那些可能一生都用不到的軟件包。

        雖然 Fedora Live 系統為我安裝的軟件包并不太多,但是如果直接更新系統,大概要下載 900 多 MB 的文件,而一份 Fedora Workstation 光盤鏡象文件不過 1.5 GB 而已。

        我刪除的一些軟件包如下

        abrt
        gnome-software
        evolution
        gnome-abrt
        gnome-weather
        gnome-contacts
        gnome-maps
        gnome-clocks
        gnome-documents
        gnome-screenshot
        gnome-disk-utility
        baobab
        gvfs-goa
        cheese
        vinagre
        open-vm-tools-desktop
        xorg-x11-drv-vmware
        lvm2
        PackageKit-glib
        chrony
        firewalld
        samba-client
        samba-common
        setroubleshoot
        shotwell
        rhythmbox
        totem

        使用 dnf remove 命令來刪除它們,例如:

        $ sudo dnf remove abrt gnome-software ...

        之所以刪除這些軟件包,是因為它們不重要。不重要就刪除嗎……不民主??!可是,刪除了它們,在更新系統的時候,可以少下載大概 400 MB 的包。

        如果你對 Fedora 以及 GNome 3 不熟悉,刪除軟件包的時候要小心。因為刪除一個軟件包的時候,Fedora 的包管理器會自動找出這個軟件包所依賴的那些軟件包,然后將它們一總刪除。如果你在刪除某個軟件包的時候,發現它所依賴的軟件包中有 gnome-shellmutter 時,如果你想重啟機器后還能進入桌面,那你就應該放棄對這個軟件包的刪除操作。

        凡事過猶不及。很多年前,有個小伙伴裝了 360 全家桶,用它對系統進行了各種優化,重啟機器就再也進不去 Windows 桌面了。在 Fedora 中,若想獲得類似感受,可試刪除 evolution-data-server 這個包:

        $ sudo dnf remove evolution-data-server

        在對自己不需要的軟件包進行延安整風,三反五反等運動之后,便可對系統進行更新了

        $ sudo dnf update

        我不需要的竟然還有那么多

        系統更新后,我重啟了系統,發現能夠正常進入桌面??磥?,搞搞整風運動還是有必要的。清除了自己看著不順眼的東西,還無傷大體。

        接下來,我運行了 gnome-system-monitor 程序,要看看系統資源的占用情況。結果發現,Fedora 還真是與時俱進,拿內存當白菜了。進入桌面后,我還啥都沒干呢,內存就用了 1 GB,而這臺機器的內存,總共不過 2 GB。我的 Gentoo 系統,跑著 Mate 桌面,開了 Firefox,兩個 Emacs 進程,兩個終端進程,一個文件管理器進程,這還剛用了 573 MB 的內存呢!

        我看了看 gnome-system-monitor 的進程列表,幾個 evolution-* 進程就用掉了 40+ MB,駐留內存(Resident Mem)是 200+ MB,而一個 Xorg 進程不過用了 12.7 MB,駐留內存不過 38.3 MB 而已。崽賣爺田心不疼啊……然而我卻只能很無奈的看著它們這么囂張,因為它們屬于 evolution-data-server 包,要刪掉它們,就意味著要刪掉整個 GNOME 3 桌面!我不禁想起了趙高,想起了十常侍,想起了魏中賢,想起了李蓮英……

        移步 /etc/xdg/autostart 目錄里逛了一圈,感覺我也可以像兩千多年前的蘇格拉底那樣來感慨一下,這個世界上,竟然有這么多東西是我不需要的??!

        $ sudo rm at-spi-dbus-bus.desktop \
                  orca-autostart.desktop \
                  caribou-autostart.desktop \
                  spice-vdagent.desktop \
                  evolution-alarm-notify.desktop \
                  tracker-extract.desktop \
                  gnome-initial-setup-copy-worker.desktop \
                  tracker-miner-apps.desktop \
                  gnome-initial-setup-first-login.desktop \
                  tracker-miner-fs.desktop \
                  gnome-keyring-pkcs11.desktop \
                  tracker-miner-rss.desktop \
                  gnome-keyring-ssh.desktop \
                  tracker-miner-user-guides.desktop \
                  gnome-welcome-tour.desktop \
                  tracker-store.desktop \
                  liveinst-setup.desktop \
                  vmware-user.desktop \
                  sealertauto.desktop

        我又查看了一下 systemd 運行的的服務,也可以關掉一批:

        $ sudo systemctl disable bluetooth.service \
                                 firewalld.service \
                                 accounts-daemon.service \
                                 ModemManager.service \
                                 abrtd.service \
                                 abrt-ccpp.service \
                                 lvm2-monitor.service \
                                 packagekit.service \
                                 gssproxy.service \
                                 avahi-daemon.service \
                                 colord.service \
                                 chronyd.service \
                                 fedora-import-state.service \
                                 livesys-late.service \
                                 livesys.service \
                                 libvirtd.service \
                                 auditd.service

        繼續關掉一些我不需要的服務(去 /etc/systemd/system 目錄實地考察后確定):

        $ sudo systemctl disable abrt-{oops,vmcore,xorg}.service \
                                 hyper{vfcopyd,vkvpd,vvssd}.service \
                                 vmtoolsd.service \
                                 nfs-client.target  remote-fs.target \
                                 spice-vdagentd.service \
                                 cups.service \
                                 lvm2-{lvmetad,lvmpolld}.socket \
                                 dmraid-activation.service

        然后,又重啟了一下系統,發現竟然還能進桌面,而且桌面占用的內存減掉 300+ MB……好神奇!

        也許更神奇的是,你按照我上面的做法弄了一遍之后,結果桌面進不去了 :)

        開箱即用的用戶體驗

        開箱即用,意思是把全人類都需要的東西裝到一個箱子里嗎?

        用戶體驗,意思是所有的用戶只有一個體驗嗎?

        我知道,Linus 也用 Fedora,但我還是喜歡 Gentoo。因為,在 Gentoo 這樣的系統中,我可以從幾乎是最簡的系統上一點一點的創建我的箱子與我的體驗。如果安裝到這臺機器上的 Fedora 有一天又被玩壞了,我會將它換成 Debian 或 Gentoo。

        后記

        幾天后,發現 GNOME 桌面運行一段時間后,就感覺機器運轉的有些生澀起來??纯戳丝磧却嬲加?,不知道啥時候,交換區都被悄悄的耗掉 37 MB。再看看 gnome-shell,占用的內存都到 350+ MB 了……這必定是存在內存泄漏的節奏啊。

        再也忍受不了……Bye,Fedora!

        接下來,我們來玩一個安裝 Debian 的游戲吧,請移步「Debian,從按安裝到喜歡」。

        查看原文

        贊 5 收藏 1 評論 4

        依云 贊了回答 · 2020-01-12

        解決是否所有支持漢字的字符編碼都兼容ascii碼?

        Unicode 不是一種編碼方式。

        UTF8 UTF16 UTF32 都是基于 Unicode 的編碼方式,其中只有 UTF8 是與 ASCII 兼容的。

        關注 2 回答 2

        依云 回答了問題 · 2020-01-12

        windows 文件監聽 ReadDirectoryChangesW

        我也不知道這是為什么,因為我沒有復現。猜測這個數字是 Vim 進程的 pid??赡苁遣寮谧鍪裁词?。你使用 vim --clean 再試試?

        PS: 這和 Windows、ReadDirectoryChangesW 有什么關系么?

        關注 2 回答 1

        依云 回答了問題 · 2020-01-12

        不允許使用 redis和memcached情況下如何限制同一用戶接口請求的頻率

        這是什么奇怪的需求。
        如果是受環境所限,沒有 Redis 和 memcached 的話。別的存儲數據的東西總有吧?比如某種數據庫。如果你是單機,用本地文件也行。如果你是單進程,數據存內存里也行。
        總之你需要有個地方來存東西。沒有記憶的話何談頻率呢?有地方存數據,然后就上個桶算法就行了。存哪算法都一樣,差別只是用什么存儲API。

        關注 5 回答 5

        依云 贊了文章 · 2019-08-07

        30 歲的女程序員:敢問路在何方?

        clipboard.png

        本文內容為作者投稿,不代表本平臺觀點
        人名均為化名,文章略有刪改

        自然而然,成了程序員

        從小,我就和一般的姑娘不太一樣。小學的時候家里就給買了一臺老式的聯想 1+1 電腦,算是打開了我新世界的大門。當時的游戲是要在 DOS 系統上運行的,進個游戲還得先敲幾行命令。這么算的話,我也是有 20 來年編程經驗的人了。

        從高中開始,我就在 BBS 和貼吧里混進了很多「黑客組織」,名字就不提了怕被認出來,影響不太好哈哈哈。當年跟著團里的大牛還爬過 QQ 的用戶信息,也就是所謂的盜號,雖然沒用來干什么壞事,但還是覺得挺刺激的。

        之后很自然的,大學專業不顧父母的反對,報了計算機,畢業當上了一名光榮的程序員戰士。

        畢業之前還挺喜歡參加社交活動的,但工作之后每次認識新朋友,介紹職業時聽到我是女程序員,第一反應是:啊,女程序員可不多見,好好的小姑娘怎么選擇當程序員了?

        接下來,他們就會給我講一個黑程序員的段子,然后我就配合著他們哈哈哈的假笑。

        但其實,我根本笑不出來,程序員是喜歡自黑,但。就因為這種事兒,硬生生的把我一個活潑開朗的少女,變成了一個技術宅。

        而困難模式的職場之旅,也就隨著畢業開始了。

        稀缺物種,糟糕的職場初體驗

        還記得畢業去的第一家公司,人不多,我應該是部門招到的唯一一個女程序員,入職第一天,人事對我說以后“上班要穿高跟鞋,穿正裝,不能再跟個學生一樣”,還給布置了一個額外的任務,“作為職場新人,要活躍團隊氣氛,多陪大家聊聊天”。

        講真的,我這算不算是業內第一個“程序員鼓勵師”?我一程序員,來公司是來上班干活兒的吧?雖說是個職場新人,但這種要求也實在是太過分了,也是因為年輕,第二天沒溝通我就直接辭職了。

        后來入職的公司還不錯,沒有什么亂七八糟的“潛規則”,但新的問題又出現了 —— 我怎么也融入不到同事的圈子里。

        部門又是只有我一個妹子,男生們可以跟領導三天兩頭吃個飯,爬個山,約個球什么,但我一女生跟著一塊兒出去玩,怎么也玩兒不到一塊兒去。

        他們平常閑聊的時候,除了聊工作,就是球賽、股票,或者男人之間的話題,我也參與不進去。好在后來有了魔獸世界和 dota ,也算是有了一點兒共同的話題,但開荒的時候他們從來都不帶我。

        現在女權主義崛起,大家都在說請不要區別對待女程序員,但就像我這種比較爺們兒的妹子,都混的很艱難,大部分的妹子程序員,可能確實和男程序員之間存在一些「社群隔離」。

        艱難的晉升之路

        前兩年因為個人原因,選擇了辭職重新找工作。連續面試了七八家,幾乎都被問到,“結沒結婚?”“有沒有男朋友?”“打算什么時候結婚呢?”“打算什么時候生小孩呀”,如果一旦被得知近期有結婚的想法,那基本就不會再聊下去了。

        有幾個熟悉的獵頭也坦白的跟我講,我這種情況現在勉強還可以找到工作,但再往后就越來越難找了,企業不會明說,但對于年齡這塊兒,還真的是有一些硬性要求的。

        大齡女程序員找工作難,想晉升更難。

        這個我想分為兩點來說:一是當領導難,二是當領導難。

        第一個難,是想當上領導,很難。

        現在的很多企業,都開始流行晉升評定前給員工做性格測試。這種規則其實沒什么問題,但無形中把很多女性排除在技術崗位之外。

        技術男胡子拉碴不修邊幅,說話刻薄冒失可以接受,這是智商高、性格宅、工作穩重踏實任勞任怨的體現,女人如果這樣,就不行;不這樣吧,又說沒有職業精神,工作態度不端正,心思不在工作上還是不行,你說氣不氣?

        上家公司的文化其實是非常務實重效率,內部很尊重每個人的話語權,也很尊重個人意見,沒什么等級概念,能力突出也會被看到,給個人的空間相對較大,工作內容的靈活度也高。

        但技術人職場的晉升,很多時候跟工作量是正相關的。而作為女程序員,或多或少是能受到一些“優待”的。

        加班領導讓比別人先走;項目出現緊急情況,男同事頂上去;連續開發階段唯一可以回家睡個踏實覺的也是我,不得不說,這是對我們女性的照顧,但最后評定業績的時候,確實不如大家付出的多,獎金、晉升的機會,也就很難得到了。

        有網友該出來杠了,你自己不加班不出力怪的了誰?

        對此我只能說,你說的對。

        clipboard.png

        第二個難,是想給別的程序員當領導,難。

        隨著工作項目的增加,老板給我們部門招了個新人,算是我的手下。他跟別人聊天時,我無意間聽到他吐槽,“我怎么跟著一個女程序員?”。

        當年我面試的時候,因為是女生被質疑;沒想到后來成了領導,還因為性別被質疑。

        職業規劃,死路一條?

        除了性別和年齡,女性程序員的職業困境也來自行業本身。如果你要問一個25歲的程序員,他的職業規劃是什么?

        基本是“跳槽,升職加薪,跳槽,升職加薪?!边@被前人給我們走出來的一條路,也是目之所及最快實現職業發展的路徑。而到了 30 歲,因為年齡的考慮,跳槽的可能性越來越低,這條路也就很難走了。

        我身邊的女程序員,最大也就 35 歲左右,40 歲以上還真沒見過了。

        對于職業規劃,我就相對比較「佛系」了。

        在中國有種普遍的想法是,作幾年技術該轉去做管理,否則你就沒前途了,這是人云亦云的說法。但我為什么不能一直做技術呢?雖然中國的大環境可能不適合一直做技術,但是我愿意試試。我不愿意放棄多年來積攢的一點點優勢。何況我現在工作上越來越得心應手。

        不過學習還是不能停的。除了逛逛社區,寫寫自己的技術專欄(我在 segmentfault 上也有專欄,但太菜怕被噴,還是匿了吧),我每天一定要抽點時間學習,最近在研究微信公眾號,打算分享一些女性程序員的生活職場感悟,先投個稿試試水~

        另外一直也在試著做自己的小項目,找出路。

        “社會正在懲罰不進步的人?!?/p>

        clipboard.png

        這句話已經被雞湯博主說爛了,但確實是這么一個道理。不管大環境怎么樣,總有一些人,在不斷變革的大時代下能抓住機會。都說今年是互聯網時代的第20個年頭,互聯網行業要求越來越高,如果不能鍛煉出相匹配的能力,那就活該被淘汰。

        clipboard.png

        后記

        說點兒閑話。我曾經和一個體制內的油膩男子相親,張口房閉口車,說互聯網行業就是瞎搞,沒前途,進了體制才是真正的在社會站穩了腳,一直忽悠我趕緊考個公務員,找個機會幫我進體制內。

        呵呵,社會可能真的很現實,但人各有志,將軍請回吧。

        相比之下,跟男程序員交流就很簡單,感覺大部分都很單純,會用一些直男的小心思來討好你,特別可愛。

        我原來喜歡浪漫的男生,現在標準已經變了,只要有原則,懂得互相尊重就行。

        作為女碼農,在工作上不太被尊重,所以生活中,想要對方能夠承認我的能力,說一句“其實你挺優秀的”,就好了。但至今都沒找到。

        PS:感謝加入過的每家公司,都是寶貴的經歷。
        PPS:感謝看這篇文章的朋友,希望你們的生活都比我要精彩~
        PPPS:去紅螺寺燒香真的管用么哈哈哈哈哈哈

        • END -

        clipboard.png

        clipboard.png

        查看原文

        贊 31 收藏 6 評論 40

        依云 回答了問題 · 2019-01-26

        解決域名 cn 與 com 的選擇

        首選 .com。如果公司有國內和國際(含港澳臺)業務,可在境內注冊 .cn(或者 .com.cn),在境外注冊 .com 來方便使用。

        關注 7 回答 6

        依云 評論了文章 · 2018-08-11

        golang 字節對齊

        最近在做一些性能優化的工作,其中有個結構體占用的空間比較大,而且在內存中的數量又特別多,就在想有沒有優化的空間,想起了 c 語言里面的字節對齊,通過簡單地調整一下字段的順序,就能省出不少內存,這個思路在 golang 里面同樣適用

        基本數據大小

        在這之前先來看下 golang 里面基本的類型所占數據的大小

        So(unsafe.Sizeof(true), ShouldEqual, 1)
        So(unsafe.Sizeof(int8(0)), ShouldEqual, 1)
        So(unsafe.Sizeof(int16(0)), ShouldEqual, 2)
        So(unsafe.Sizeof(int32(0)), ShouldEqual, 4)
        So(unsafe.Sizeof(int64(0)), ShouldEqual, 8)
        So(unsafe.Sizeof(int(0)), ShouldEqual, 8)
        So(unsafe.Sizeof(float32(0)), ShouldEqual, 4)
        So(unsafe.Sizeof(float64(0)), ShouldEqual, 8)
        So(unsafe.Sizeof(""), ShouldEqual, 16)
        So(unsafe.Sizeof("hello world"), ShouldEqual, 16)
        So(unsafe.Sizeof([]int{}), ShouldEqual, 24)
        So(unsafe.Sizeof([]int{1, 2, 3}), ShouldEqual, 24)
        So(unsafe.Sizeof([3]int{1, 2, 3}), ShouldEqual, 24)
        So(unsafe.Sizeof(map[string]string{}), ShouldEqual, 8)
        So(unsafe.Sizeof(map[string]string{"1": "one", "2": "two"}), ShouldEqual, 8)
        So(unsafe.Sizeof(struct{}{}), ShouldEqual, 0)
        • bool 類型雖然只有一位,但也需要占用1個字節,因為計算機是以字節為單位
        • 64為的機器,一個 int 占8個字節
        • string 類型占16個字節,內部包含一個指向數據的指針(8個字節)和一個 int 的長度(8個字節)
        • slice 類型占24個字節,內部包含一個指向數據的指針(8個字節)和一個 int 的長度(8個字節)和一個 int 的容量(8個字節)
        • map 類型占8個字節,是一個指向 map 結構的指針
        • 可以用 struct{} 表示空類型,這個類型不占用任何空間,用這個作為 map 的 value,可以講 map 當做 set 來用

        字節對齊

        結構體中的各個字段在內存中并不是緊湊排列的,而是按照字節對齊的,比如 int 占8個字節,那么就只能寫在地址為8的倍數的地址處,至于為什么要字節對齊,主要是為了效率考慮,而更深層的原理看了一下網上的說法,感覺不是很靠譜,就不瞎說了,感興趣可以自己研究下

        // |x---|
        So(unsafe.Sizeof(struct {
            i8 int8
        }{}), ShouldEqual, 1)

        簡單封裝一個 int8 的結構體,和 int8 一樣,僅占1個字節,沒有額外空間

        // |x---|xxxx|xx--|
        So(unsafe.Sizeof(struct {
            i8  int8
            i32 int32
            i16 int16
        }{}), ShouldEqual, 12)
        
        // |x-xx|xxxx|
        So(unsafe.Sizeof(struct {
            i8  int8
            i16 int16
            i32 int32
        }{}), ShouldEqual, 8)

        這兩個結構體里面的內容完全一樣,調整了一下字段順序,節省了 33% 的空間

        // |x---|xxxx|xx--|----|xxxx|xxxx|
        So(unsafe.Sizeof(struct {
            i8  int8
            i32 int32
            i16 int16
            i64 int64
        }{}), ShouldEqual, 24)
        
        // |x-xx|xxxx|xxxx|xxxx|
        So(unsafe.Sizeof(struct {
            i8  int8
            i16 int16
            i32 int32
            i64 int64
        }{}), ShouldEqual, 16)

        這里需要注意的是 int64 只能出現在8的倍數的地址處,因此第一個結構體中,有連續的4個字節是空的

        type I8 int8
        type I16 int16
        type I32 int32
        
        So(unsafe.Sizeof(struct {
            i8  I8
            i16 I16
            i32 I32
        }{}), ShouldEqual, 8)

        給類型重命名之后,類型的大小并沒有發生改變

        轉載請注明出處
        本文鏈接:http://hatlonely.com/2018/03/...
        查看原文

        依云 評論了文章 · 2018-07-20

        為什么要用Redis

        最近閱讀了《Redis開發與運維》,非常不錯。這里對書中的知識整理一下,方便自己回顧一下Redis的整個體系,來對相關知識點查漏補缺。

        我按照五點把書中的內容進行一下整理:

        ?    為什么要選擇Redis:介紹Redis的使用場景與使用Redis的原因;
        ?    Redis常用命令總結:包括時間復雜度總結與具體數據類型在Redis內部使用的數據結構;
        ?    Redis的高級功能:包括持久化、復制、哨兵、集群介紹;
        ?    理解Redis:理解內存、阻塞;這部分是非常重要的,前面介紹的都可以成為術,這里應該屬于道的部分。;
        ?    開發技巧:主要是一些開發實戰的總結,包括緩存設計與常見坑點。
        

        先來開啟第一部分的內容,對Redis來一次重新打量。

        本系列內容基于:redis-3.2.12

        Redis不是萬金油

        在面試的時候,常被問比較下Redis與Memcache的優缺點,個人覺得這二者并不適合一起比較,一個是非關系型數據庫不僅可以做緩存還能干其它事情,一個是僅用做緩存。常常讓我們對這二者進行比較,主要也是由于Redis最廣泛的應用場景就是Cache。那么Redis到底能干什么?又不能干什么呢?

        Redis都可以干什么事兒

        緩存,毫無疑問這是Redis當今最為人熟知的使用場景。再提升服務器性能方面非常有效;

        排行榜,如果使用傳統的關系型數據庫來做這個事兒,非常的麻煩,而利用Redis的SortSet數據結構能夠非常方便搞定;

        計算器/限速器,利用Redis中原子性的自增操作,我們可以統計類似用戶點贊數、用戶訪問數等,這類操作如果用MySQL,頻繁的讀寫會帶來相當大的壓力;限速器比較典型的使用場景是限制某個用戶訪問某個API的頻率,常用的有搶購時,防止用戶瘋狂點擊帶來不必要的壓力;

        好友關系,利用集合的一些命令,比如求交集、并集、差集等??梢苑奖愀愣ㄒ恍┕餐糜?、共同愛好之類的功能;

        簡單消息隊列,除了Redis自身的發布/訂閱模式,我們也可以利用List來實現一個隊列機制,比如:到貨通知、郵件發送之類的需求,不需要高可靠,但是會帶來非常大的DB壓力,完全可以用List來完成異步解耦;

        Session共享,以PHP為例,默認Session是保存在服務器的文件中,如果是集群服務,同一個用戶過來可能落在不同機器上,這就會導致用戶頻繁登陸;采用Redis保存Session后,無論用戶落在那臺機器上都能夠獲取到對應的Session信息。

        Redis不能干什么事兒

        Redis感覺能干的事情特別多,但它不是萬能的,合適的地方用它事半功倍。如果濫用可能導致系統的不穩定、成本增高等問題。

        比如,用Redis去保存用戶的基本信息,雖然它能夠支持持久化,但是它的持久化方案并不能保證數據絕對的落地,并且還可能帶來Redis性能下降,因為持久化太過頻繁會增大Redis服務的壓力。

        簡單總結就是數據量太大、數據訪問頻率非常低的業務都不適合使用Redis,數據太大會增加成本,訪問頻率太低,保存在內存中純屬浪費資源。

        選擇總需要找個理由

        上面說了Redis的一些使用場景,那么這些場景的解決方案也有很多其它選擇,比如緩存可以用Memcache,Session共享還能用MySql來實現,消息隊列可以用RabbitMQ,我們為什么一定要用Redis呢?

        速度快,完全基于內存,使用C語言實現,網絡層使用epoll解決高并發問題,單線程模型避免了不必要的上下文切換及競爭條件;
        注意:單線程僅僅是說在網絡請求這一模塊上用一個請求處理客戶端的請求,像持久化它就會重開一個線程/進程去進行處理

        豐富的數據類型,Redis有8種數據類型,當然常用的主要是 String、Hash、List、Set、 SortSet 這5種類型,他們都是基于鍵值的方式組織數據。每一種數據類型提供了非常豐富的操作命令,可以滿足絕大部分需求,如果有特殊需求還能自己通過 lua 腳本自己創建新的命令(具備原子性);

        除了提供的豐富的數據類型,Redis還提供了像慢查詢分析、性能測試、Pipeline、事務、Lua自定義命令、Bitmaps、HyperLogLog、發布/訂閱、Geo等個性化功能。

        Redis的代碼開源在GitHub,代碼非常簡單優雅,任何人都能夠吃透它的源碼;它的編譯安裝也是非常的簡單,沒有任何的系統依賴;有非?;钴S的社區,各種客戶端的語言支持也是非常完善。另外它還支持事務(沒用過)、持久化、主從復制讓高可用、分布式成為可能。

        做為一個開發者,對于我們使用的東西不能讓它成為一個黑盒子,我們應該深入進去,對它更了解、更熟悉。今天簡單說了下Redis的使用場景,以及為什么選擇了Redis而不是其它。下次對Redis的內部數據結構及常用命令的時間復雜度進行總結。

        公眾號-dayuTalk

        查看原文

        依云 評論了文章 · 2018-07-14

        解決 vim 報錯:the imp module is deprecated in favour of importlib

        問題描述

        打開 vim 之后,出現如下錯誤:

        Error detected while processing function youcompleteme#Enable[3]..<SNR>71_SetUpPython:
        line   42:
        /must>not&exist/foo:1: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses

        原因:
        這是 python warning。
        imppython3.4 之后 已經不再使用。
        顯然,這個問題是由 ycm 這個插件加載時引起的,可以通過修改 ycm 源碼解決。

        解決辦法

        有以下幾種:
        1.重新安裝 vim,但是采用較低版本的 python
        2.修改 ycm 報錯部分的代碼
        具體修改如下:
        vim PLUG_PATH/YouCompleteMe/autoload/youcompleteme.vim
        修改如下:

        diff --git a/autoload/youcompleteme.vim b/autoload/youcompleteme.vim
        index 597eb020..32461fa9 100644
        --- a/autoload/youcompleteme.vim
        +++ b/autoload/youcompleteme.vim
        @@ -180,7 +180,7 @@ endfunction
        
        
         function! s:SetUpPython() abort
        -  exec s:python_until_eof
        +  silent! exec s:python_until_eof
         from __future__ import unicode_literals
         from __future__ import print_function
         from __future__ import division

        參考:Error message printed first time python3 (version 3.7.0) dynamic library is imported


        更新:這個問題出現在使用 Python 3.7 的情況,
        可以暫時在 .vimrc 中做如下配置,并等待更新 Python 3.7 來解決這個問題:

        " temporary fix
        " https://github.com/vim/vim/issues/3117
        if has('python3')
          silent! python3 1
        endif
        查看原文

        認證與成就

        • 獲得 1810 次點贊
        • 獲得 62 枚徽章 獲得 4 枚金徽章, 獲得 20 枚銀徽章, 獲得 38 枚銅徽章

        擅長技能
        編輯

        開源項目 & 著作
        編輯

        注冊于 2011-07-19
        個人主頁被 23.7k 人瀏覽

        一本到在线是免费观看_亚洲2020天天堂在线观看_国产欧美亚洲精品第一页_最好看的2018中文字幕