bt365体育投注.主頁欢迎您!!

    <acronym id="zvmrr"></acronym>
    <td id="zvmrr"></td>
  • <tr id="zvmrr"><label id="zvmrr"></label></tr>
  • <acronym id="zvmrr"></acronym>
  • 依云

    依云 查看完整档案

    北京编辑  |  填写毕业院校  |  填写所在公司/组织 blog.lilydjwg.me/ 编辑
    编辑

    即日起我不在此查看可以回答的问题。

    在这里,我遇到了一些问题,比如乱打标签,比如解决了不标记为解决,甚至言语攻击。时间不应该浪费在这些不尊重回答者的用户上。

    想要我帮忙解决技术问题,可以向我付费提问: http://www.wgoodp.icu/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,常缩写为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 上也有专栏,但太菜怕被喷,还是匿了吧),我每天一定要抽点时间学习,最近在研究微信公众号,打算分享一些女性程序员的生活职场感悟,先投个稿试试水~

    另外一直也在试着做自己的小项目,找出路。

    “社会正在惩罚不进步的人。”

    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,代码非常简单优雅,任何人都能够吃透它的源码;它的编译安装也是非常的简单,没有任何的系统依赖;有非常活跃的社区,各种客户端的语言支持也是非常完善。另外它还支持事务(没用过)、持久化、主从复制让高可用、分布式成为可能。

    做为一个开发者,对于我们使用的东西不能让它成为一个黑盒子,我们应该深入进去,对它更了解、更熟悉。今天简单说了下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
    查看原文

    认证与成就

    • 获得 1808 次点赞
    • 获得 61 枚徽章 获得 3 枚金徽章, 获得 20 枚银徽章, 获得 38 枚铜徽章

    擅长技能
    编辑

    开源项目 & 著作
    编辑

    注册于 2011-07-19
    个人主页被 22.3k 人浏览

    bt365体育投注