精华内容
下载资源
问答
  • 我要偷偷的学Python,然后惊呆所有人(最后一天

    万次阅读 多人点赞 2020-12-14 16:05:12
    时隔20,也该给这个系列画上个句号啦。 后期我会对这个系列进行个整合,预计会整理为13篇,不用担心,是原地整理,一般不会删博客。 这篇不是爬虫相关,是我重新梳理了Python的相关知识之后,发现了一些和...

    在这里插入图片描述

    前言

    时隔20天,也该给这个系列画上一个句号啦。
    后期我会对这个系列进行一个整合,预计会整理为13篇,不用担心,是原地整理,一般不会删

    展开全文
  • 亲密接触Redis-第一天

    万次阅读 多人点赞 2016-02-03 17:10:24
    网上唯一一篇真正正确的教你如何使用redis,避免在使用过程因为对redis不够了解而在以后实施的过程碰到各种严重瓶劲的教程,教程内不仅讲述了redis的使用还讲述了如何使用docker来搭建自己的redis微服务以及使用...

    引言

    nosql,大规模分布式缓存遍天下,Internet的时代在中国由其走得前沿,这一切归功于我国特色的电商。因此nosql、大数据技术在中国应用的比国外还要前沿。从这一章开始我们将开始进入到真正的SOA、PAAS、SAAS、互联网的领域,因此每一篇我都会加入一小段业务的基础知识,让大家在学习技术的同时也可以了解一些业务,这边的业务不是指的business logic不是让大家去做业务人员,而是为大家带来IDEA,”没有做不到只有想不到“,阿里支付宝为什么发了。。。不是技术,而是它的IDEA。


    业务基础知识-国内国外电商比较以及为什么电商技术在中国走得这么前沿

    14年1月时在上海参加过一个MagentoCom召集的电商峰会。会上一群LAO WAI在那边大谈自己的电商经验,有LV,有ADIDAS,bla...bla...bla...听着听着,真是觉得好笑。休息时随便问一个LAO WAI一个问题:


    ”你们知道什么叫一元秒杀吗?“


    ”你们知道什么7天无理由退货吗?“


    ”你们知道什么叫0体验吗?“


    ”你们有没有双11,双12,有没有交易量过亿。。。“


    LAO WAI ”张嘴,流哈喇子,billions of transaction? billions“


    看着他这个样子,我是硬忍住后来到WC一边抽烟一边笑,笑得连手上的烟头都抖了,唉。。。。。。


    不是说国外的电商不这么干,而是经济体制决定了电商的发展道路不同,因为国外的电商是基于他们的”信任“式经济的模式下的,因此国外的电商基本都是信用卡、预先冲款、预售卡、充值卡这些,这也决定了国外没有什么1元秒杀。。。这些哄人气的东东。


    另外一点就是国外人口也少,呵呵,这算是一个理由。


    还有就是国外基本无”不是名牌“这一说,记得去法国onsite交流学习时,如果你穿的一件ADIDAS或者是NIKE或者是阿玛尼如果不是正宗名牌,是仿的话也会被警察抓住罚款,因此国外是个商品基本都有牌子。这是一种”互信“机制。


    中国的电商虽然也是走线上、线下但是它多了一个”第三方资金委托“即支付宝、易宝、微信(微信是后起之秀)这种东东,因此这样的体制决定了”先验货,后付钱“的这种游戏规则。


    加上中国人多,这下大数据、NOSQL、分布式这些技术当然成为了通向internet的重中之重了。


    进入Redis课程

    Redis是什么

    Redis是一个NOSQL,NOSQL有许多种,它们分为:

    • 列存储,如:Hbase、Cassandra这种
    • 文档存储,如:MongoDB(首推)
    • key-value存储,如:Berkeley DB、MemcacheDB、Redis,其中Redis最强
    • 图存储,这块基本不用,有:Neo4j、Versant
    • XML存储,如:Berkeley DB Xml还有XBASE,ORACLE很早已经支持这种存储方式了

    光知道这些NOSQL的名词是没有用的,关键在于要知道在哪种场景下选用哪种NOSQL才是我们真正要去掌握的。

    我们这边说Redis就拿Redis说事吧,它能干什么呢?


    Redis基础应用场景

    • web间session共享,即多个war工程共享一个session
    • 分布式缓存,因为redis为键值对,而且它提供了丰富的adapter可以支持到C、.net、java客户端,因此对于异质平台间进行数据交换起到了作用,因此它可以用作大型系统的分布式缓存,并且其setnx的锁常被用于”秒杀“,”抢红包“这种电商活动场景中。

    安装Redis

    我本来想在这儿写”Redis上的‘坑‘“,最后我还是觉得把它放到后面章节中去写吧,因为中国人的思维是先有感性再有理性的一种逆向思维,其实这点很像美国人,因此中国人在世界上是最聪明的民族之一,所以我们还是先从动手搭一个Redis的环境来说起吧,老规矩, 红色加粗很重要。

    一定要使用Linux来布署Redis,请不要偷懒使用Redis 2.8.1 for windows那个版本,如果你使用了这个版本你将无法跟上这一系列教程的步伐。因为Redis为GCC+这样的东西开发出来的,它天生就是运行在LINUX/Unix环境下的,而 那个windows版的Redis是一个”烟“割版,而且是一个unofficial的版本非官方授权的哈。

    先从Docker开始

    如果已经有Linux/Unix环境的同协们可以直接跳过这一章。

    我们这边要开始变态了,因为我们要真正开始踏上SOA、PAAS、互联网的脚步了。

    如果对于没有Linux/Unix环境的用户来说,我在这边推荐使用docker,即boot2docker windows版来安装,它下载后是一个这样的文件


    安装前把你的网络连接中的IPV6协议前的勾去掉

    双击它,在安装时记得选择Virtual-Box选项,因为docker本为linux/unix下之物,因此为了在windows下使用docker,boot2docker内嵌了一个virtualbox来虚拟docker的环境。
    装完后它会在你的桌面上生成一个蓝色的图标,双击它,它会打开一个绿色的字,黑色的背景像matrix电影里的那种命令行窗口,这就是Docker。

    装完后运行:
    docker@boot2docker:~$ docker run hello-world 

    看到下面这些提示


    Hello from Docker. 
    
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps: 
    1. The Docker client contacted the Docker daemon. 
    2. The Docker daemon pulled the “hello-world” image from the Docker Hub. 
    (Assuming it was not already locally available.) 
    3. The Docker daemon created a new container from that image which runs the 
    executable that produces the output you are currently reading. 
    4. The Docker daemon streamed that output to the Docker client, which sent it 
    to your terminal.
    
    To try something more ambitious, you can run an Ubuntu container with: 
    $ docker run -it ubuntu bash
    
    For more examples and ideas, visit: http://docs.docker.com/userguide/

    说明你的Docker安装成功了。

    在Docker中安装unix环境


    有了Docker我们就用Docker虚拟一个Ubuntu(UNIX)环境吧,在这边我们使用的是Ubuntu14。

    ubuntu14请下载这个包: 戳: 下载Ubuntu14包

    下载后直接在docker下运行下面这条命令:

    cat ubuntu-14.04-x86_64.tar.gz |docker import - ubuntu:ubuntu14

    这个过程会很快,完成后查看自己的image:



    成功导入了ubuntu,这样我们就可以在docker中运行出一个自己的ubuntu了。


    docker run -i -t ubuntu:ubuntu14 /bin/bash

    以上运行后,进入了该ubuntu的bash环境。


    注:如果上述命令出错,可以使用下面这条命令:

    docker run -i -t ubuntu:ubuntu14 //bin/bash

    两个 “/” 

    如果你能看到类似于root@ubuntu14_这样的命令行界面说明你的ubuntu14也已经安装成功了,下面我们就要在这个docker->ubuntu14中安装和布署我们的Redis了,这个过程和在linux下一样。


    在ubuntu14下先安装SSHD,以便于我们使用WINSCP这样的SFTP工具来管理我们的ubuntu14中的文件系统


    在ubuntu14中安装SSHD

    第一步:

    docker run -t -i ubuntu/mk:v1 /bin/bash


    进入我们的ubuntu环境,这边的ubuntu/mk就是我本机的docker中ubuntu14 container(容器)的名字,如果按照上面的延续此处可以替换成ubuntu:ubuntu14这个名字吧。


    第二步:

    升级一下你的apt-get,它就是一个命令行IE下载工具,如果你不update,那么你apt-get的源、内核都为旧的,因此为了升级apt-get请键入下面的命令

    apt-get update


    这个过程很快(依赖于你的网络环境)


    第三步:


    下载和安装openssh组件

    apt-get install openssh-server openssh-client


    第四步:


    修改你的root密码

    passwd


    键入两次你的root密码,我这边都为6个小写的a


    第五步:

    退出容器,并保存以上修改,如果docker在退出后你接着退出docker环境或者是关机那么刚才的4步全部不生效,你一定要commit它才能生效,为此:

    • 你先要知道你刚才用docker run命令运行的ubuntu14的容器的ID,你可以使用
      docker ps -a
      来查到你latest的一次容器的ID,它是一组16进制一样的编码如:1edfb9aabde8890,有了这个container id我们就可以commit我们刚才装的openssh的环境了
    • commit刚才在容器中所做的修改
      docker commit 1edfb9aabde8890 ubuntu:ssh

    第六步:

    运行带有openssh的ubuntu14以便于我们使用winscp这样的SFTP工具连入我们的ubuntu14中去,依次输入下面的命令:

    docker kill $(docker ps -q)


    杀掉正在运行的所有的container的进程

    docker rm $(docker ps -a -q)


    删除所有在进程中的容器,以上2步又被称为docker大扫除


    Docker是这样的机制的,它可以开启多个容器,每个容器带着一堆的image(镜像),要删一个镜像必须先停止这个镜像所在的容器,再把这个镜像删除,因此我们使用上面这两条命令对于Docker来一个大扫除。


    接着我们先查一下我们目前手头有的镜像

    docker images
    你会看到一个images列表,里面有我们的ubuntu:14,有我们的ubuntu:ssh也有一个hello-world,我们把ubuntu:14这个镜像删了吧(为了保持干净哈)


    每个image也它自己的id,即image id,因此你用docker images命令查到该镜像的id后可以使用:


    docker rmi imageid
    这条命令把一个不用的镜像给删了。


    接下去我们要启动我们的ubuntu14:ssh了,可以使用下面这条命令:

    docker -d -p 122:22 ubuntu:ssh //usr/sbin/sshd -D

    这条命令的意思为:

    • -d即把我们的image启动在后台进程,它将会是一个daemon进程,而不会像刚才我们使用-t一样,一旦exit后该image进程也自动退出了
    • -p为端口映射,什么意思呢,这边要说一下docker的端口映射问题。我们知道docker安装后它会利用virtualbox中的vhost only的nat机制来建立一个虚拟的IP
    可以打开我们的virtualbox中在菜单”全局->设定->网络”中进行查找


    所以我们可以知道一旦boot2docker环境运行后它的地址为192.168.56.*这个段,一般为192.168.56.101这个地址,你可以在boot2docker启动后直接使用winscp边入这个docker环境。

    地址:192.168.56.101
    端口:22
    用户名:docker
    密码:tcuser

    以上为默认值,具体地址按照你的virtualbox中在boot2docker安装时自动给出的设置来做参考。

    而,
    我们在这个docker中安装了一个ubuntu14:ssh的image,然后用后台进程的方式打开了这个ubuntu14:ssh,因此它自己也有一个IP(可能是172也可能是169段),具体不得而知,一般来说它是每次启动镜像后自己变换的(可以使用动态网络域名绑定docker中镜像的ip来达到域名不变的目的-集群环境下有用)。

    我们都知道ssh是以端口22来进行TCP连接的,因此我们把ubuntu14的IP上的22端口映射到了我们的docker主机192.168.56.101上的122端口。

    • 参数//usr/sbin/sshd -D代表该镜像启动会的entrypoint即启动后再启动一个什么命令,在最后的-D(大写的D)告诉docker这是一个启动文件
    于是,一旦该命令发出后,显示image启动的提示后(启动后你会得到一个image id)你就可以直接打开你的winscp使用:


    地址:192.168.56.101
    端口:122 (此处是122,不是22,因为我们把image的22端口映射到了192.168.56.101-docker主机上的122端口了)
    用户名:root
    密码:aaaaaa

    即可以连入我们的ubuntu14环境了,如果此时你安装了putty还可以使用putty+winscp直接进入ubuntu14的命令行环境中去,于是你就有ubuntu14的试验环境了。





    在ubuntu14下安装redis

    网上很多在ubuntu14下安装redis的教程都不对的,大家看了要上当的,原因在于如下,请各位看完:

    1. 网上的redis环境搭建直接使用的是apt-get update完后用wget https://github.com/ijonas/dotfiles/raw/master/etc/init.d/redis-server 这样的方式来安装的,这样装固然方便,可是也因为方便所以取到的redis不是最新的redis版本,一般为2.8.x版或者是redis3.0.rc,这依赖于你的unit/linux所连接的wget库
    2. redis为c写成,它的2.4-2.8版都为不稳定版或者是缺少功能或者是有bug,而这些bug在你如果真正使用redis作为网站生产环境时将会因为这些bug而无法面对峰涌而来的巨大并发,因此当有这样的redis运行了一段时间后你的生产环境会面临着巨大的压力
    3. 还是redis不够新不够稳定的原因,由于在redis3前redis还不支持集群、主备高可用方案的功能,因此不得不依靠于繁杂的打补丁式的如:linux/unix-keepalive或者是haproxy这种系统级层面然后写一堆的复杂脚本去维护你的redis集群,还要用外部手段(Linux/Unix Shell脚本)去维护多个redis节点间的缓存数据同步。。。这这这。。。不复合我们的网站扩容、增量、运维和面对巨大用户(万级并发-最高支持百万用户如:新浪微博、微信)的场景
    因此,我在这边推荐大家使用下面我将要使用的“下载源码包结合你本机的Linux/Unix内核进行实时编译”的安装过程。

    第一步:下载redis目前最稳定版本也是功能最完善,集群支持最好并加入了sentinel(哨兵-高可用)功能的redis3.0.7版即redis-stable版,为此我们需要获取redis-stable版

    就是用的这个redis-stable.tar.gz包,这是我在写博客时目前最新最稳定版本,修复了大量的BUG和完善了功能。

    第二步:

    下载后我们把该包上传到我们的docker中的ubuntu14中,我们把它放在/opt目录下

    然后我们使用tar -zxvf redis-stable.tar.gz对它进行解压


    解压后它就会生成一个redis-stable目录,进入该目录 cd redis-stable


    别急,我们先一会编译和安装它


    第三步:编译安装redis

    我们先输入gcc -v 这个命令来查看我们的gcc版本,如果它低于4.2以下那么你在编译redis3.0.7时一定会碰到大量的出错信息,如前面所述,redis为gcc写成,最新的redis需要gcc4.2-5这个版本才能进行编译,而一般去年或者之前装的linux/unix 的 gcc都为4.0以下或者甚至是3.x版。

    升级GCC先

    apt-get install build-essential


    因此apt-get update显得很重要,要不然你获取的gcc也将不是最新的版本,目前我的gcc为5.3.1为这周刚做的升级。


    升级后我们开始编译redis3.0.7了,为此我们需要在redis-stable目录下


    键入如下命令:

    make PREFIX=/usr/local/redis1 install

    我们告知我们的GCC把redis-stable编译并同时安装在/usr/local/redis1目录下


    这个过程很快,可能只有10秒钟时间(依据你的机器来说,建议使用>=8gb, 4核CPU的PC机),然后我们就可以看到everything ok了。我们进入/usr/local/redis1就可以看到我们刚才安装的redis3.0.7稳定版了。


    我们进入我们的redis目录 cd /usr/local/redis1/bin


    在此目录下我们即可以运行我们的redis server了,不过请别急,在启动前我们需要对redis进行一些配置。


    我的博客面对的是“全栈式”工程师的,架构师只是成为全栈式工程师中的一个起点,如果你不会搭环境那么你就不能接触到最新的技术,因此这就是许多程序员工作了近5年,7年结果发觉也只会一个SSH的主要原因。

    Redis3配置要领

    使用winscp通过122连入docker下的ubuntu14,进行redis的配置。

    我们需要编辑的文件为/usr/local/redis1/bin/redis.conf这个文件

    daemonize yes
    
    # When running daemonized, Redis writes a pid file in /var/run/redis.pid by
    # default. You can specify a custom pid file location here.
    pidfile "/var/run/redis/redis1.pid"
    
    # Accept connections on the specified port, default is 6379.
    # If port 0 is specified Redis will not listen on a TCP socket.
    port 7001
    
    我们把:

    1. daemonize设为yes,使得redis以后台进程的方式来运行,你可以认为为“server”模式,如果redis以server模式运行的话它会生成一个pid文件 ,因此我们把它的路径放在/var/run/redis目录中,并命名它为redis1.pid文件 ,为此你需要在/var/run目录下建立redis这个目录
    2. 端口号我们把它设为7001,这样好辩识,因为将来我们会进一步做redis集群,所以我们的redis都为redis1, redis2, redis3那么我们的端口号也为7001, 7002, 7003。。。这样来延续。那么很多同协这时要问了,“为什么我们不把它命名成master, slave1, slave2这样的名字呢?”,理由很简单,无论是现在的hadoop还是zookeeper它们的集群是跨机房的,多个master间也有MASTER-SLAVE模式互为备份,因为一些大型网站不仅仅只有一个IDC机房,它们一般都会有2个,3个IDC机房,或者是在同一个IDC机房中有“跨机柜”的布署来形成超大规模集群,就和ALI的TAOBAO网一样,它在北美都有机房,因此当你需要在LOCAL NATIVE建一个IDC机房,在北美再做一个机房,你不要想把一个MASTER设在中国,SLAVE设到美国去,而是多地甚至是多机柜都有MASTER,一旦一个MASTER宕机了,这种集群会通过一个叫“选举策略”选出一个节点把这个节点作为当前“群”的MASTER,因此我们的命名才会是redis1, redis2, redis3...这样来命名的。


    此处把原来的:
    save 900 1
    save 300 10
    save 60 10000
    中的300 10 和60 10000注释掉。这边代表的是:

    redis以每900秒写一次、300秒写10次,60秒内写1万次这样的策略把缓存放入一个叫.rdb的磁盘文件中,这点和ehcache或者是memcache很像,以便于redis在重启时可以从本地持久化文件中找出关机前的数据记录。

    如果按照默认的话,此三个策略会轮流起效,在大并发环境中,这样的写策略将会对我们的性能造成巨大的影响,因此我们这边只保留900秒写1次这条策略, 这边有人会问,如果你这样会有数据丢失怎么办。。。别急,这个问题我们后面会解答,这涉及到redis的“正确”使用,如果它只是一个缓存,我相信5分钟内缓存的丢失此时程序直接访问数据库也不会有太大问题,又要保证数据完整性又要保证性能这本身是一个矛与盾的问题,除非你钱多了烧那我会给出你一个烧钱的配置策略,连新浪都不会这么烧钱,呵呵。

    • dbfilename,此处我们维持redis原有的缓存磁盘文件的原名
    • dir "/usr/local/redis1/data"为rdb文件所在的目录
    这边大家要注意的是一个是只能写文件名,另一个地方只能写目录名。
    为此我们需要在/usr/local/redis1下建立 data目录。



    把此处的appendonly设为no,这样我们就关闭了Redis的AOF功能。

    • AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF是redis在集群或者是高可用环境下的一个同步策略,它会不断的以APPEND的模式把redis的缓存中的数据从一个节点写给另一个节点,它对于数据的完整性保证是要高于rdb模式的。
    • RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。RDB 非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心如阿里的mysql异地机房间使用FTP传binlog的做法。
    按照官方的说法,启用AOF功能,可以在redis高可用环境中如果发生了故障客户的数据不会有高于2秒内的历史数据丢失,它换来的代价为高昂的I/O开销,有些开发者为了追求缓存中的数据100%的正确有时会碰到因为redis在AOF频繁刷新时整个环境如死机一的情况,并且你会看到恶梦一般的”Asynchronous AOF fsync is taking too long “警告信息, 这是因为redis它是单线程的,它在进行I/O操作时会阻塞住所有的操作,包括登录。。。这个很可怕,不过这个BUG/ISSUE已经在最新redis中进行了优化,它启用了另一根进程来进行AOF刷新,包括优化了RDB持久化功能, 这也是为什么我让大家一定一定要用最新最稳定版的redis的原因

    一般默认情况下redis内的rdb和AOF功能同为开启,

    如果RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。

    因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,所以我只保留save 900 1这条规则。


    如果Enalbe AOF:

    • 好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。
    • 代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写,这边可以设定一个适当的数值。


    如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉极大的IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉(那你的网站基本也就歇了),会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构。



    最后我们不要忘了设一个redis的log文件,在此我们把它设到了/var/log/redis目录,为此我们需要在/var/log目录下建立一个redis目录。

    好了,保存后我们来启动我们的redis吧。

    我们使用以下这条命令来启动我们的redis server。



    然后我们在我们的windows机上装一个windows版的redis 2.8.1 for windows(只用它来作为redis的client端)

    然后我们在windows环境下使用:

    redis-cli -p 7001 -h 192.168.56.101

    咦,没反映,连不上,哈哈。。。。。。

    那是肯定连不上的,因为:

    1. 我们刚才在用docker启动ubuntu14时使用docker -d -p 122:22 ubuntu:ssh //usr/sbin/sshd -D来启动的,这边我们并未把redis服务的7001端口映射到192.168.56.101这台docker主机上,怎么可以通过windows主机(可能windows的ip为169.188.xx.xx)来访问docker内的进程服务呢?对吧,为此我们:先把刚才做了这么多的更改docker commit成一个新的image如:redis:basic吧。
    2. 然后我们对docker进行一次大扫除,然后我们启动redis:basic这个image并使用以下命令:
    docker -d -p 122:22 -p 7001:7001 redis:basic //usr/sbin/sshd -D

    看,此处我们可以使用多个-p来作docker内容器的多端口映射策略(它其实使用的就是iptables命令)。

    好了,用putty连入这个image的进程并启动redis服务,然后我们拿windows中的redis-cli命令来连。


    如果在linux环境下还是没有连通(可能的哦),那是因为你没有禁用linux下的防火墙,我们可以使用iptables -F来禁用linux的防火墙或者使用:


    vi /etc/selinux/config

    然后把

    SELINUX=enforcing     这句用”#“注释掉
    增加一句: SELINUX=disabled  #增加

    这样每次启动后linux都不会有iptables的困扰了(这是在本机环境下这么干哦,如果你是生产环境请自行加iptables策略以允许redis服务端口可以被访问)。


    看到下面这个PONG即代表你的redis服务已经在网络环境中起效了。



    下面我们要开始使用JAVA客户端来连我们的Redis Service了。


    使用Spring Data + JEDIS来连接Redis Service

    Spring+Session+Redis

    pom.xml

    在此我们需要使用spring data和jedis,下面给出相关的maven配置

    	<dependencies>
    		<!-- poi start -->
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi</artifactId>
    			<version>${poi_version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-ooxml-schemas</artifactId>
    			<version>${poi_version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-scratchpad</artifactId>
    			<version>${poi_version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-ooxml</artifactId>
    			<version>${poi_version}</version>
    		</dependency>
    		<!-- poi end -->
    		<!-- active mq start -->
    		<dependency>
    			<groupId>org.apache.activemq</groupId>
    			<artifactId>activemq-all</artifactId>
    			<version>5.8.0</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.activemq</groupId>
    			<artifactId>activemq-pool</artifactId>
    			<version>${activemq_version}</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.xbean</groupId>
    			<artifactId>xbean-spring</artifactId>
    			<version>3.16</version>
    		</dependency>
    		<!-- active mq end -->
    
    		<!-- servlet start -->
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>servlet-api</artifactId>
    			<version>${javax.servlet-api.version}</version>
    			<scope>provided</scope>
    		</dependency>
    		<dependency>
    			<groupId>javax.servlet.jsp</groupId>
    			<artifactId>jsp-api</artifactId>
    			<version>2.1</version>
    			<scope>provided</scope>
    		</dependency>
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>jstl</artifactId>
    			<version>1.2</version>
    		</dependency>
    		<!-- servlet end -->
    
    		<!-- redis start -->
    		<dependency>
    			<groupId>redis.clients</groupId>
    			<artifactId>jedis</artifactId>
    			<version>2.7.2</version>
    		</dependency>
    		<dependency>
    			<groupId>org.redisson</groupId>
    			<artifactId>redisson</artifactId>
    			<version>1.0.2</version>
    		</dependency>
    		<!-- redis end -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>jcl-over-slf4j</artifactId>
    			<version>${slf4j.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-log4j12</artifactId>
    			<version>${slf4j.version}</version>
    		</dependency>
    
    		<!-- spring conf start -->
    		<dependency>
    			<groupId>org.springframework.data</groupId>
    			<artifactId>spring-data-redis</artifactId>
    			<version>1.6.2.RELEASE</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-webmvc</artifactId>
    			<version>${spring.version}</version>
    			<exclusions>
    				<exclusion>
    					<groupId>commons-logging</groupId>
    					<artifactId>commons-logging</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-tx</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-aop</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-context-support</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.data</groupId>
    			<artifactId>spring-data-redis</artifactId>
    			<version>1.6.2.RELEASE</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-orm</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-jms</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.session</groupId>
    			<artifactId>spring-session</artifactId>
    			<version>${spring.session.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-core</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<!-- spring conf end -->
    	</dependencies>


    redis-config.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation="  
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    	<context:property-placeholder location="classpath:/spring/redis.properties" />
    	<context:component-scan base-package="org.sky.redis">
    	</context:component-scan>
    
    	<bean id="jedisConnectionFactory"
    		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    		<property name="hostName" value="${redis.host.ip}" />
    		<property name="port" value="${redis.host.port}" />
    		<property name="poolConfig" ref="jedisPoolConfig" />
    	</bean>
    
    	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    		<property name="maxTotal" value="${redis.maxTotal}" />
    		<property name="maxIdle" value="${redis.maxIdle}" />
    		<property name="maxWaitMillis" value="${redis.maxWait}" />
    		<property name="testOnBorrow" value="${redis.testOnBorrow}" />
    		<property name="testOnReturn" value="${redis.testOnReturn}" />
    	</bean>
    	<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
    		<property name="connectionFactory" ref="jedisConnectionFactory" />
    	</bean>
    
    	<!--将session放入redis -->
    	<bean id="redisHttpSessionConfiguration"
    		class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
    		<property name="maxInactiveIntervalInSeconds" value="1800" />
    	</bean>
    	<bean id="customExceptionHandler" class="sample.MyHandlerExceptionResolver" />
    </beans> 


    redis.properties

    redis.host.ip=192.168.0.101
    redis.host.port=6379
      
    
    redis.maxTotal=1000  
    redis.maxIdle=100
    redis.maxWait=2000
    redis.testOnBorrow=false
    redis.testOnReturn=true
    


    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    	<!-- - Location of the XML file that defines the root application context 
    		- Applied by ContextLoaderListener. -->
    	<!-- tag::context-param[] -->
    	<context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>
    			classpath:/spring/redis-conf.xml
    		</param-value>
    	</context-param>
    	<!-- end::context-param[] -->
    
    	<!-- tag::springSessionRepositoryFilter[] -->
    	<filter>
    		<filter-name>springSessionRepositoryFilter</filter-name>
    		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    	</filter>
    	<filter-mapping>
    		<filter-name>springSessionRepositoryFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    	<session-config>
    		<session-timeout>30</session-timeout>
    	</session-config>
    	<!-- end::springSessionRepositoryFilter[] -->
    	<filter>
    		<filter-name>encodingFilter</filter-name>
    		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    		<init-param>
    			<param-name>encoding</param-name>
    			<param-value>UTF-8</param-value>
    		</init-param>
    		<init-param>
    			<param-name>forceEncoding</param-name>
    			<param-value>true</param-value>
    		</init-param>
    	</filter>
    
    	<filter-mapping>
    		<filter-name>encodingFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    
    	<servlet>
    		<servlet-name>dispatcher</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>classpath:/spring/spring-mvc.xml</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>dispatcher</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>
    
    	<!-- - Loads the root application context of this web app at startup. - 
    		The application context is then available via - WebApplicationContextUtils.getWebApplicationContext(servletContext). -->
    	<!-- tag::listeners[] -->
    	<listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    	<!-- end::listeners[] -->
    
    	<servlet>
    		<servlet-name>sessionServlet</servlet-name>
    		<servlet-class>sample.SessionServlet</servlet-class>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>sessionServlet</servlet-name>
    		<url-pattern>/servlet/session</url-pattern>
    	</servlet-mapping>
    
    	<welcome-file-list>
    		<welcome-file>index.jsp</welcome-file>
    	</welcome-file-list>
    
    </web-app>

    这边主要是一个:

            <filter>
    		<filter-name>springSessionRepositoryFilter</filter-name>
    		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    	</filter>
    	<filter-mapping>
    		<filter-name>springSessionRepositoryFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    	<session-config>
    		<session-timeout>30</session-timeout>
    	</session-config>
    这个filter一定要写在一切filter之前


    SessionController

    package sample;
    
    import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    /**
     * Created by mk on 15/1/7.
     */
    @Controller
    @EnableRedisHttpSession
    public class SessionController {
    	@RequestMapping("/mySession")
    	public String index(final Model model, final HttpServletRequest request) {
    		if (request.getSession().getAttribute("testSession") == null) {
    			System.out.println("session is null");
    			request.getSession().setAttribute("testSession", "yeah");
    		} else {
    			System.out.println("not null");
    		}
    		return "showSession";
    	}
    
    }
    

    showSession.jsp文件

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>showSession</title>
    </head>
    <body>
    <%
    	String sessionValue=(String)session.getAttribute("testSession");
    %>
    
    <h1>Session Value From Servlet is: <%=sessionValue%></h1>
    </body>
    </html>

    测试

    保证我们的redise-server是启动的,然后我们启动起这个web工程后使用:

    http://localhost:8080/webpoc/mySession访问一下这个controller

    此时我们使用redis客户端工具连入查看spring session是否已经进入到了redis中去。

    在redis客户端工具连入后我们可以在redis console中使用keys *来查看存入的key,LOOK,spring的session存入了redis中去了。


    再来看我们的eclipse后台,由于我们是第一次访问这个controller,因此这个session为空,因此它显示如下:


    我们在IE中再次访问该controller


    由于之前的session已经存在于redis了,因此当用户在1800秒(30分钟)内再次访问controller,它会从session中获取该session的key testSession的值,因此eclipse后台打印为not null。

    SpringRedisTemplate + Redis

    讲过了spring session+redis我们来讲使用spring data框架提供的redisTemplate来访问redis service吧。说实话,spring这个东西真强,什么都可以集成,cassandra, jms, jdbc...jpa...bla...bla...bla...Spring集成Barack Hussein Obama? LOL :)


    pom.xml

    不用列了,上面有了

    redis-conf.xml

    不用列了,上面有了

    web.xml

    也不用列了,上面也有了

    SentinelController.java

    我们就先用这个名字吧,后面我们会用它来做我们的redis sentinel(哨兵)的高可用(HA)集群测试

    package sample;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.data.redis.core.BoundHashOperations;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisSentinelPool;
    import util.CountCreater;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    /**
     * Created by xin on 15/1/7.
     */
    @Controller
    public class SentinelController {
    
    	@Autowired
    	private StringRedisTemplate redisTemplate;
    
    	@RequestMapping("/sentinelTest")
    	public String sentinelTest(final Model model,
    			final HttpServletRequest request, final String action) {
    		return "sentinelTest";
    	}
    
    	@ExceptionHandler(value = { java.lang.Exception.class })
    	@RequestMapping("/setValueToRedis")
    	public String setValueToRedis(final Model model,
    			final HttpServletRequest request, final String action)
    			throws Exception {
    		CountCreater.setCount();
    		String key = String.valueOf(CountCreater.getCount());
    		Map mapValue = new HashMap();
    		for (int i = 0; i < 1000; i++) {
    			mapValue.put(String.valueOf(i), String.valueOf(i));
    		}
    		try {
    			BoundHashOperations<String, String, String> boundHashOperations = redisTemplate
    					.boundHashOps(key);
    			boundHashOperations.putAll(mapValue);
    			System.out.println("put key into redis");
    		} catch (Exception e) {
    			e.printStackTrace();
    			throw new Exception(e);
    		}
    		
    		return "sentinelTest";
    	}
    
    
    }
    

    打开IE,输入:http://localhost:8080/webpoc/setValueToRedis

    观察我们的后台


    然后使用redis client连入后进行查看


    看。。。这个值key=1的,就是我们通过spring的redisTemplate存入进去的值,即使用下面这段代码进行存入的值:

     for (int i = 0; i < 1000; i++) {
    	mapValue.put(String.valueOf(i), String.valueOf(i));
    }
    try {
    	BoundHashOperations<String, String, String> boundHashOperations = redisTemplate.boundHashOps(key);
    	boundHashOperations.putAll(mapValue);


    如何你要存入一个简单的如key=test value=hello,你可以这样使用你的redisTemplate

    redisTemplate.execute(new RedisCallback<Object>() {
    
    			@Override
    			public Object doInRedis(RedisConnection connection)
    					throws DataAccessException {
    				connection.set(
    						redisTemplate.getStringSerializer().serialize(
    								"test"), redisTemplate
    								.getStringSerializer()
    								.serialize("hello"));
    				return null;
    			}
    });


    是不是很方便的哈?结束第一天的教程,明天开始搭建redis集群。



    展开全文
  • 回过头来,帅地已经毕业一年多了,下面跟大家扯扯我普普通通的四大学吧 大一 大一第学期这部分的事情最多了,所以会写的多一些,因为我觉得,在大一,我的思维发生了很大的改变,大一过后,我的想法、计划就...

    大家好,我是帅地。

    双非校招拿大厂提前批 offer

    在校期间从 0 到 1 摸索出一个 10 万垂直粉丝公众号

    毕业半年依靠工作与副业挣到人生第一个 100 万

    回过头来,帅地已经毕业一年多了,下面跟大家扯一扯我普普通通的四年大学吧

    大一

    大一第一学期这部分的事情最多了,所以会写的多一些,因为我觉得,在大一,我的思维发生了很大的改变,大一过后,我的想法、计划就基本有着落了,后面基本事按照自己的计划,去做自己喜欢的事了。

    大一第一学期的第一要务:转专业

    看过我之前文章的读者可能都知道,我大一第一学期不是计算机专业的,读的专业是木材科学与工程。当然,这不是我自己选择的专业,而是高考分数不够,被调剂的专业,我自己热爱的专业是计算机类专业,还没有进入大学之前,我就说我一定要读编程相关的专业了。

    说实话,我很庆幸自己最后转到了计算机类的专业,一个很现实的原因就是,学编程,真的能够挣钱,而且你愿意努力学的话,你一毕业就能够拿到很高的工资,本科毕业,有好些可以拿到年薪 50 万,你敢信?就算工资很低,也都能年薪十几万,当然,我不能暴露自己的工资,暴露了就要被公司劝退了。

    是的,我读计算机专业,有两个重要的原因,一个原因就是热爱,一个是家里穷,我想挣钱,改变家里的现状。

    所以在我大一第一学期那一会,我的目标就很明确,这学期的任务就是转专业,所以我了解了转专业的各种规则,了解到转专业的一个最基本的要求就是数学和英语需要 85 分以上才能参与考试。

    85 分很难吗?不难;但是如果需要你保证 85 分难吗?说实话,有一些,因为万一考不好呢?考不好就得大二转了,所以我第一学期,英语的平时分,我给刷到了 100 分,也就是满分。数学是我的强项,但我依然不敢掉以轻心,在考前把 2006-2015 年的试卷都刷了一两遍。

    有这样的准备,数学和英语的分数那必须杠杠,实不相瞒,大一学期的绩点是我整个大学的巅峰,然而,三等奖依然没有拿到!!!因为我只学了这两门,其他随意,不挂科即可。

    当然,85 分只是一个门槛,转专业的竞争还是挺激烈。我选了软件工程,参与人数大概是差不多 60 人,不过学院只接 15 个人(后来好像是录取了 20 人),所以为了稳一些,我在第一学期就把 c 语言自学了一遍,把学校的 OJ 题库,第一学期相关的编程题,给刷了一两遍。

    说实话,有了这样的准备,转专业想不成功都难,考试 2 小时,我不到半个小时就离开考场了,等待录取通知了。

    有必要加入社团吗?

    对于刚步入大学的同学来说,社团是一个比较有趣的玩意,绝大部分人都会去加入自己喜欢的社团吧。

    我进入大学之前,很多人说,在大学,要多交点人脉,多认识一些朋友,因为这些人会成为你后面很重要的资源,所以我去加入一些社团,其实是想多认识一些人。

    然而,我去面试了两个社团,都在二面被刷了,说实话,对于面试,我还是有点恐惧的,反正就是挺紧张,后来我就干脆不去面试了,不加入社团了。

    后来我就加入了他们的会员,之前面试那个,是成为他们的干部。成为会员则不需要面试,不过需要交会员费用,所以我就顺便成为了几个社团的会员,例如羽毛球,爱心社团啥的。

    不过,我去参与了一两次社团的活动之后,就没在去了,一个简单的原因就是,我不大喜欢,我还是喜欢去做自己喜欢的事。我是一个懒散,喜欢自由,不喜欢被束缚的人,所以我觉得,我还是不去参加这些活动了。

    回答刚才的问题,有必要加入社团吗?,可能很多人会觉得,必须要加入社团,不然大学就不完整了,我的想法则是,加入社团不是一个必选项,加与不加,我觉得都没事,看你自己的喜欢。

    加入社团能学到很多东西吗?能学到一些,但这些没啥的,对于以后找工作,我觉得属于可有可无。如果你自己愿意学习,学习能力比较强,在哪里都可以学到很多东西。

    摆脱的社团之后,我基本就什么组织也没参加了,然后我宿舍也有一个和我一样比较逗比+沙雕的,我俩就经常去外面溜达,看到有趣的活动,就去参与一波,反正完全看心情,报名了活动,交了钱,心情不好就不去参加了,美滋滋(感觉要被喷,哈哈)

    有必要多认识些人吗?

    我刚才说了,我希望自己在大学多认识些人,多泛交些朋友,后来经过第一学期的感悟,我发现,这没必要,在大学,大家基本都在忙各自的事情,我本来还想在大学找几个挚友,以后一起干大事,但经过一学期的观察,发现这很难,当然,很难不代表不存在。

    总之,对于现在还在大一大二的学生,如果你有这方面的疑问,那么我给的建议是,没必要刻意去交朋友,其实后面大家都各自去做自己的事情了,毕竟找到一些经的起时间考验的志同道合的朋友,很不容易。

    第二学期:落差之后的折腾

    大一学期其实可以写的还有非常非常多,因为第一学期,我的任务就两门课程,还是非常闲,期间也发生了非常多改变我想法多事情,不过一不小心就两千多字了,还是不继续写了,后面的时光可能就没有第一学期那么丰富了,相对比较枯燥了。

    经过了第一学期,成功进入了软件工程,自己也没参与什么社团,并且大学想要干点事,例如创业之类的,因为没读大学之前,经常听说创业这事……总之,进入大学的时候,感觉前途一片光明,我觉得我要干非常非常多的事,但进入大学之后,发现并没有啥战绩。

    庆幸的事,我完成了一个非常坚定的目标,那便是转专业。转过来软工之后,我也想干点大事,例如 acm 拿个牛逼的奖牌,或者写个牛逼的软件出来,因为经常听到某某人开发了一个 xx,然后就成名了。

    然而,学了 c 语言,发现啥也写不出来,学了算法,发现 acm 那些题也太难了,一道题做一天,还是没做出来,答案也看不懂,发现自己并不是大神,脑子也并没有大佬转的快。

    后来,我就不打算参加 acm 了,感觉如果自己要拿到名次,肯定会花很多时间,并且不一定拿的到,加上我看到班里也有人退出 acm 集训队了,这更加坚定了我的想法。

    听说数据结构与算法很重要,所以我早早就把数据结构与算法这门课学完了,我第二学期学的最多的就是数据结构 + 算法这两门课,虽然不参加 ACM,但算法还是得学,会点算法听说会显的牛逼一些。

    暑假的折腾

    大一暑假那会,虽然数据结构与算法学的还不错,不过发现啥东西的做不出来,C 语言写的程序都是黑乎乎的界面,然后我就学了 windows 程序编程,这样我就可以写个程序给身边的人玩了,毕竟我是学编程的,至少得写个作品出来给别人玩啊。

    在暑假花了十几天,把那本 900 多页的windows程序编程刷了 700 多页,写了个计算器,后来发现身边的人还是玩不了,因为很多人没电脑,于是我就对 windows 编程没兴趣了,想着写个程序能够在手机运行就好了,于是花了十几天学了 android 编程,刷完了《第一行代码》这本书,顺便入门了 Java,跟着书写了个天气预报,还是挺开心。

    不过我又改变主意了,想着要是能挣到钱就更好了,于是我发现把 app 上传到商店,然后植入广告,就可以挣钱了,于是我买了一些实战类 android 项目的书籍,写了几个 app,自己改版之后传到了应用商店。

    然而,没啥人下载,于是我又放弃搞安卓了,后来想写个网站,然后放一些资源,让别人来下载好像也有机会挣钱,于是我学习了 HTML,CSS,JavaScript,然后又不了了之……

    这两个月的暑假,我感觉自己搞了好多东西,好多都是半途放弃,实不相瞒,驱动我去折腾这些事有两个原因:挣钱 + 装逼

    说实话,我做什么事情,都需要驱动力,我觉得驱动力对我来说太重要了,这个驱动力可以很虚,但必须得有,而我又是一个俗人,能够挣钱,是我最大的驱动力。

    当初我玩斗地主,驱动力是挣 Q 币,后来我发现这些 Q 币好像不能充 QQ会 员还是怎么的,我就放弃不玩了。

    这段折腾,我觉得让我慢慢摸清了自己的方向,所以在这里,对于大一或者大二的同学,如果你们有自己感兴趣的,或许可以去尝试一波。

    别人可能会说,这搞一下,那搞一下,会导致样样都会,但样样不精。而我的想法是:完全可以去尝试,大学的学习,不存在精通这一说法,大一大二多尝试,大三确定自己的方向来学习完全来得及。

    大二

    经过大一的洗礼,我觉得我的目标相对比较明确了,该玩的玩了,该折腾的折腾了,现在得好好规划下自己的未来了。我了解到校招时大厂非常看重基础,于是我大二就一直在学习基础,例如计算机网络,算法,操作系统这些,怎么学?

    得有动力啊,于是我报名了中级软考,这算是我一个动力,这门考试会考整个大学涉及到的知识,于是为了搞定这个软考,我大二把很多课程都学了,后面软考也顺利通过了。

    中级软考有必要参加吗?答是随便,这个证没啥含金量的,我的目的是让他督促我学习基础知识,适合用来复习知识吧。

    如果自己能坚持学,其实我是不建议浪费时间去考

    总之,大一,我学了很多数据结构和算法相关知识,大二,我学了很多基础知识 + Java 的知识,并且大二比较专心,啥比赛,啥活动也没参加,我说了,我喜欢做自己喜欢做的事,喜欢跟着自己的步伐走,别人的建议,我可能会参考下,但我无论做什么事,都有自己的想法和思考。

    有人也有问,有必要加入实验室吗?,我没加过实验室,但我想说的是,加与不加,都没关系,重点是你想学习什么,想成为什么样的人,实验室,更多的是一种气氛,但不一定适合你。要是我加入实验室,我可能会把实验室当作一个学习的场地,进而去学习自己喜欢的东西。

    也有人问,那些基础知识很枯燥,有没有什么办法?,答是没有,有些本来就枯燥,但枯燥的东西,往往是决定你我之间的区别,如果都很有趣,那大家肯定也都学,正是因为困难,所以才有了人与人之间的区别。

    大三

    2018 年我大三了,大三的我,可能是大一大二学了太多东西了,大三我可以说是慢慢开辟了一条新的赛道,并且新赛道也和我之前大一大二学所的知识相辅相成,那就走上了写作这条路,从此开启了自己开挂的人生。

    我写的文章有多受欢迎?

    在 CSDN 仅发 100 多篇文章,便收获几百万阅读量。

    image-20210923183023512

    更有单篇阅读量近百万的文章,2019 年底 ~ 2020 年那会可以说是 CSDN 的大红人。

    image-20210924115215075

    知乎也完美收获了万赞文章,而且还是动态规划这样有难度的算法

    image-20210924115427957

    很幸运的是,不仅在写作上取得了很好的成就,在秋招上,也是早早就在提前批拿到了腾讯的 offer,可以说刚读准大四,我就结束了自己的秋招了。

    image-20210923183525854

    作为一名双非,没有任何实习经历,任何比赛经历的本科生,之所以能够拿到大公司的 offer,是因为我很早就知道大公司喜欢考什么,自己应该学什么,有自己的一套面试方法。

    而学历不好的人,意识早,真的非常重要,不然就是毕业 = 失业。

    9月份当别人还在埋头准备秋招的时候,我已经告别的秋招去探索新的方向了。

    2020.6 我毕业了,并且赶在毕业前自己送给了自己一份礼物:一个刚好 10 万粉丝的微信公众号。

    2020 年底当别人在准备年终答辩的时候,我已经挣到了人生第一个一百万了:毕业半年,帅地人生的第一个一百万

    如今的我,已经毕业一年多了,虽然说在技术上不是多厉害,但在面试、校招,大学职业规划,写作,副业上,比绝大部分人都要优秀。

    所以在这两年中,我回复了别人无数次问题,应该也影响了好多好多人,每当校招季都会很多人来报喜,我也很开心,帮助别人,真的可以让自己很有成就感

    image-20210924122859883

    不过我的微信好友太多了,每天各种问题咨询我,然而很多的问题,都是类似的,大部分是自己没好好学习,迷茫之类的,帅地也没有那么多的精力去一一答复大家,很多情况都是很简短回答一下。

    所以呢,帅地创建了一个专注于校招|大学生成长|专治各种迷茫的知识星球

    在这个星球里,我会非常详细回答大家的问题,并且这些问题可以沉淀下来,帅地也会分享面试、校招,大学职业规划,写作,副业这方面的内容等等。

    作为过来人一路折腾过来,相信一定可以给你带来很多参考价值。

    要么不做,要么就尽最大的努力去做好,所以呢,假如你是要参加校招的大学生,非科班等等,绝对非常适合你,有帅地在前面带路,一定可以让你少走很多弯路。

    帅地会在知识星球提供如下服务

    一、咨询服务:沉淀答疑,少走弯路

    这两年帅地回答了很多问题,例如 offer 选择,学习规划,大部分人都是迷茫的,不知道自己该干啥。

    而且,大部分都是类似的问题,帅地精力有限,无法一一回复,而如今有了知识星球,那些具有代表性的问题都可以沉淀下来,相信可以帮助大家少走一些弯路。

    而这个星期最大的好处就是,你可以在星球问帅地任何问题,职业选择,简历修改,校招,面试,可以定制化咨询问题,和我一对一提问,这是你在其它地方找不到的,帅地会非常详细回答你们,例如

    image-20210923184938534

    随着问题的积累,会沉淀的越来越多,大家有什么疑问,都可以搜到到,这样可以更好着帮助大家往相对「正确」的方向去学习一些东西。

    二、提供各类学习资料 + 完整的学习攻略

    为了让大家物所超值,这个星球会提供各类学习资源,例如优质的项目,视频教程,书籍等等。

    目前 Java项目,前端优质项目已提供,球友专属,后续C++,Python等项目也会陆续提供,随便一个项目,去购买都得上百元了

    image-20210922141250057

    这些项目有没有用,看看球友的答复就知道了,基本每个项目都是精心筛选,而不是那些培训班的项目,太臃肿了。

    并且帅地会提供完整的学习攻略,那些未来目标是想要找工作的,跟着我提供的学习攻略一步一个脚印走就行了

    三、帅地每周分享

    帅地每周不定时都会分享一些心得感悟,这些基本都是自己摸索出来的一些经验,说不定,就有某一篇分享影响了你的一生

    image-20210924125954702

    四、简历修改

    简历面试指导,而且是一对一,对症下药,部门球友通过我的指导,我告诉他应该如何回答,之后立马拿了几个offer。

    image-20210922142117164

    简历是面试的第一道门槛,如果你学历很牛逼,拿过很多奖牌,随便怎么写都行,但是你普普通通,那么一份简洁的简历,就显的非常重要了。

    五、CSDN 下载服务

    如果需要csdn下载自己又没有积分的,可以直接把链接甩到我微信,我看到会给你下载

    image-20210922142822000

    六、副业指导

    如果你想做副业,帅地也会把我的各种副业运营经验告诉你,在副业,运营引流这方面,经常被人称为布道师。 帅地会不定时分享自己的副业运营经验,基本有问必答,都是帅地实打实的心得干货。

    七、每逢节日发红包

    不说了,我应该是最发红包最勤奋的博主了,基本每逢节日都会发红包,有帅地,不孤单

    image-20210922142356684

    七、星球成为你的最强后盾

    在星球里的同学,基本都是热爱学习的小伙伴,在这样的环境下,相信你也会慢慢变的优秀起来,从我读书到工作,我深刻明白身边环境的重要性,在这个星球,你会收获很多小伙伴。

    目前已经有 450 + 的小伙伴在星球里了

    image-20210923185402358

    如果你信得过帅地,那么帅地邀请你加入,这个星球,将会成为你坚强的后盾。

    由于维护星球需要花费很大的精力 + 过滤一部分,该星球是付费的,价格是 119元。

    前 200 名加入,可以领取下方优惠卷****20 元,支付 99 元加入,这可能会成为你人生的关键!

    image-20210922143447973

    99 元,一顿饭的钱,可能,这将会改变你的一身也不一定。

    别的不敢保证,星球的资料 + 简历修改 + 量身定制的回答,早就超过 99 元的价格了,总之,物所超值,帅地也期待你的加入

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YyzUJMeD-1632640639809)(https://gitee.com/iamshuaidi/picture/raw/master/picture/%E6%B5%B7%E6%8A%A5%20(1)].png)

    展开全文
  • 最近有小伙伴面试,对数据结构和算法比较头疼,我整理了波资料,帮助大家快速掌握数据结构和算法的面试,感觉有用的下伙伴,点赞支持哦! 不叨叨,直接上干货。 目录 Q1:数据结构和算法的知识点整理: Q2:...

    最近有小伙伴面试,对数据结构和算法比较头疼,我整理了一波资料,帮助大家快速掌握数据结构和算法的面试,感觉有用的小伙伴,点赞支持哦!

    文末附硬核面试资料!

    不叨叨,直接上干货。

    目录

    Q1:数据结构和算法的知识点整理:

    Q2:链表,队列和栈的区别

    Q3: 简述快速排序过程

    Q4:快速排序算法的原理

    Q5:简述各类算法时间复杂度、空间复杂度、稳定性对比

    Q6:什么是 AVL 树?

     Q7:什么是红⿊树? 

     Q8:AVL 树和红⿊树的区别?

    Q9:B 树和B+ 树的区别?

    Q10:排序有哪些分类?

     Q11:直接插⼊排序的原理?

    Q12:希尔排序的原理?

    Q13:直接选择排序的原理? 

     Q14:堆排序的原理?

    Q15:冒泡排序的原理?

    Q16:快速排序的原理?

     Q17:循环和递归,你说下有什么不同的点?

    Q18:排序算法怎么选择?


    Q1:数据结构和算法的知识点整理:


     数据结构和算法的需要掌握的知识点,我的好朋友启舰整理的:


    Q2:链表,队列和栈的区别

    链表是一种物理存储单元上非连续的一种数据结构,看名字我们就知道他是一种链式的结构,就像一群人手牵着手一样。链表有单向的,双向的,还有环形的。

    队列是一种特殊的线性表,他的特殊性在于我们只能操作他头部和尾部的元素,中间的元素我们操作不了,我们只能在他的头部进行删除,尾部进行添加。就像大家排队到银行取钱一样,先来的肯定要排到前面,后来的只能排在队尾,所有元素都要遵守这个操作,没有VIP会员,所以走后门插队的现象是不可能存在的,他是一种先进先出的数据结构。我们来看一下队列的数据结构是什么样的。

    栈也是一种特殊的线性表,他只能对栈顶进行添加和删除元素。栈有入栈和出栈两种操作,他就好像我们把书一本本的摞起来,最先放的书肯定是摞在下边,最后放的书肯定是摞在了最上面,摞的时候不允许从中间放进去,拿书的时候也是先从最上面开始拿,不允许从下边或中间抽出来。

    Q3: 简述快速排序过程

    1)选择一个基准元素,通常选择第一个元素或者最后一个元素,

    2)通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的元素值比基准值大。

    3)此时基准元素在其排好序后的正确位置

    4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。

    Q4:快速排序算法的原理


    是对冒泡排序的⼀种改进,不稳定,平均/最好时间复杂度 O(nlogn),元素基本有序时最坏时间复杂度O(n²),空间复杂度 O(logn)。


    ⾸先选择⼀个基准元素,通过⼀趟排序将要排序的数据分割成独⽴的两部分,⼀部分全部⼩于等于基准     元素,⼀部分全部⼤于等于基准元素,再按此⽅法递归对这两部分数据进⾏快速排序。
    快速排序的⼀次划分从两头交替搜索,直到 low 和 high 指针重合,⼀趟时间复杂度 O(n),整个算法的时间复杂度与划分趟数有关。


    最好情况是每次划分选择的中间数恰好将当前序列等分,经过 log(n) 趟划分便可得到⻓度为 1 的⼦表, 这样时间复杂度 O(nlogn)。


    最坏情况是每次所选中间数是当前序列中的最⼤或最⼩元素,这使每次划分所得⼦表其中⼀个为空表   , 这样⻓度为 n 的数据表需要 n 趟划分,整个排序时间复杂度 O(n²)。
     

    Q5:简述各类算法时间复杂度、空间复杂度、稳定性对比

    排序算法平均时间复杂度最坏时间复杂度空间复杂度是否稳定
    冒泡排序O(n2)O(n2)O(n2)O(n2)O(1)O(1)
    选择排序O(n2)O(n2)O(n2)O(n2)O(1)O(1)不是
    直接插入排序O(n2)O(n2)O(n2)O(n2)O(1)O(1)
    归并排序O(nlogn)O(nlogn)O(nlogn)O(nlogn)O(n)O(n)
    快速排序O(nlogn)O(nlogn)O(n2)O(n2)O(logn)O(logn)不是
    堆排序O(nlogn)O(nlogn)O(nlogn)O(nlogn)O(1)O(1)不是
    希尔排序O(nlogn)O(nlogn)O(ns)O(ns)O(1)O(1)不是
    计数排序O(n+k)O(n+k)O(n+k)O(n+k)O(n+k)O(n+k)
    基数排序O(N∗M)O(N∗M)O(N∗M)O(N∗M)O(M)O(M)


    Q6:什么是 AVL 树?

     AVL 树 是平衡⼆叉查找树,增加和删除节点后通过树形旋转重新达到平衡。右旋是以某个节点为中⼼, 将它沉⼊当前右⼦节点的位置,⽽让当前的左⼦节点作为新树的根节点,也称为顺时针旋转。同理左旋     是以某个节点为中⼼,将它沉⼊当前左⼦节点的位置,⽽让当前的右⼦节点作为新树的根节点,也称为    逆时针旋转。

     
    Q7:什么是红⿊树?
     

    红⿊树 是 1972 年发明的,称为对称⼆叉 B 树,1978 年正式命名红⿊树。主要特征是在每个节点上增加⼀个属性表示节点颜⾊,可以红⾊或⿊⾊。

    红⿊树和 AVL 树 类似,都是在进⾏插⼊和删除时通过旋转保持⾃身平衡,从⽽获得较⾼的查找性能。与 AVL 树 相⽐,红⿊树不追求所有递归⼦树的⾼度差不超过 1,保证从根节点到叶尾的最⻓路径不超过最短路径的 2 倍,所以最差时间复杂度是 O(logn)。

    红⿊树通过重新着⾊和左右旋转,更加⾼效地完成了插⼊和删除之后的⾃平衡调整。红⿊树在本质上还是⼆叉查找树,它额外引⼊了 5 个约束条件: ① 节点只能是红⾊或⿊⾊。 ② 根节点必须是⿊⾊。 ③ 所有 NIL 节点都是⿊⾊的。 ④ ⼀条路径上不能出现相邻的两个红⾊节点。 ⑤ 在任何递归⼦树中,根节点到叶⼦节点的所有路径上包含相同数⽬的⿊⾊节点。


    这五个约束条件保证了红⿊树的新增、删除、查找的最坏时间复杂度均为    O(logn)。如果⼀个树的左⼦节点或右⼦节点不存在,则均认定为⿊⾊。红⿊树的任何旋转在 3 次之内均可完成。

     
    Q8:AVL 树和红⿊树的区别?


    红⿊树的平衡性不如 AVL 树,它维持的只是⼀种⼤致的平衡,不严格保证左右⼦树的⾼度差不超过 1。这导致节点数相同的情况下,红⿊树的⾼度可能更⾼,也就是说平均查找次数会⾼于相同情况的 AVL 树。


    在插⼊时,红⿊树和 AVL 树都能在⾄多两次旋转内恢复平衡,在删除时由于红⿊树只追求⼤致平衡,因此红⿊树⾄多三次旋转可以恢复平衡,⽽ AVL 树最多需要 O(logn) 次。AVL 树在插⼊和删除时,将向上回溯确定是否需要旋转,这个回溯的时间成本最差为 O(logn),⽽红⿊树每次向上回溯的步⻓为 2,回溯成本低。因此⾯对频繁地插⼊与删除红⿊树更加合适。


    Q9:B 树和B+ 树的区别?

     
    B 树中每个节点同时存储 key 和 data,⽽ B+ 树中只有叶⼦节点才存储 data,⾮叶⼦节点只存储 key。InnoDB 对 B+ 树进⾏了优化,在每个叶⼦节点上增加了⼀个指向相邻叶⼦节点的链表指针,形成了带有顺序指针的 B+ 树,提⾼区间访问的性能。


    B+ 树的优点在于: ① 由于 B+ 树在⾮叶⼦节点上不含数据信息,因此在内存⻚中能够存放更多的key,数据存放得更加紧密,具有更好的空间利⽤率,访问叶⼦节点上关联的数据也具有更好的缓存命     中率。 ② B+树的叶⼦结点都是相连的,因此对整棵树的遍历只需要⼀次线性遍历叶⼦节点即可。⽽ B 树则需要进⾏每⼀层的递归遍历,相邻的元素可能在内存中不相邻,所以缓存命中性没有 B+树好。但是 B 树也有优点,由于每个节点都包含 key 和 value,因此经常访问的元素可能离根节点更近,访问也更迅速。


    Q10:排序有哪些分类?

    排序可以分为内部排序和外部排序,在内存中进⾏的称为内部排序,当数据量很⼤时⽆法全部拷⻉到内存需要使⽤外存,称为外部排序。


    内部排序包括⽐较排序和⾮⽐较排序,⽐较排序包括插⼊/选择/交换/归并排序,⾮⽐较排序包括计数/  基数/桶排序。
     
    插⼊排序包括直接插⼊/希尔排序,选择排序包括直接选择/堆排序,交换排序包括冒泡/快速排序。

     
    Q11:直接插⼊排序的原理?

     稳定,平均/最差时间复杂度 O(n²),元素基本有序时最好时间复杂度 O(n),空间复杂度 O(1)。
    每⼀趟将⼀个待排序记录按其关键字的⼤⼩插⼊到已排好序的⼀组记录的适当位置上,直到所有待排序 记录全部插⼊为⽌。


    直接插⼊没有利⽤到要插⼊的序列已有序的特点,插⼊第 i 个元素时可以通过⼆分查找找到插⼊位置insertIndex,再把 i~insertIndex 之间的所有元素后移⼀位,把第 i 个元素放在插⼊位置上。

    Q12:希尔排序的原理?

     
    ⼜称缩⼩增量排序,是对直接插⼊排序的改进,不稳定,平均时间复杂度 O(n^1.3^),最差时间复杂度O(n²),最好时间复杂度 O(n),空间复杂度 O(1)。


    把记录按下标的⼀定增量分组,对每组进⾏直接插⼊排序,每次排序后减⼩增量,当增量减⾄ 1 时排序完毕。

    Q13:直接选择排序的原理?
     

    不稳定,时间复杂度 O(n²),空间复杂度 O(1)。


    每次在未排序序列中找到最⼩元素,和未排序序列的第⼀个元素交换位置,再在剩余未排序序列中重复     该操作直到所有元素排序完毕。

     
    Q14:堆排序的原理?


     是对直接选择排序的改进,不稳定,时间复杂度 O(nlogn),空间复杂度 O(1)。


    将待排序记录看作完全⼆叉树,可以建⽴⼤根堆或⼩根堆,⼤根堆中每个节点的值都不⼩于它的⼦节点     值,⼩根堆中每个节点的值都不⼤于它的⼦节点值。


    以⼤根堆为例,在建堆时⾸先将最后⼀个节点作为当前节点,如果当前节点存在⽗节点且值⼤于⽗节点,就将当前节点和⽗节点交换。在移除时⾸先暂存根节点的值,然后⽤最后⼀个节点代替根节点并作 为当前节点,如果当前节点存在⼦节点且值⼩于⼦节点,就将其与值较⼤的⼦节点进⾏交换,调整完堆     后返回暂存的值。


    Q15:冒泡排序的原理?


     稳定,平均/最坏时间复杂度 O(n²),元素基本有序时最好时间复杂度 O(n),空间复杂度 O(1)。
     
    ⽐较相邻的元素,如果第⼀个⽐第⼆个⼤就进⾏交换,对每⼀对相邻元素做同样的⼯作,从开始第⼀对     到结尾的最后⼀对,每⼀轮排序后末尾元素都是有序的,针对 n 个元素重复以上步骤 n -1 次排序完毕。


    当序列已经有序时仍会进⾏不必要的⽐较,可以设置⼀个标志记录是否有元素交换,如果没有直接结束⽐较。

    Q16:快速排序的原理?


     
    是对冒泡排序的⼀种改进,不稳定,平均/最好时间复杂度 O(nlogn),元素基本有序时最坏时间复杂度O(n²),空间复杂度 O(logn)。


    ⾸先选择⼀个基准元素,通过⼀趟排序将要排序的数据分割成独⽴的两部分,⼀部分全部⼩于等于基准     元素,⼀部分全部⼤于等于基准元素,再按此⽅法递归对这两部分数据进⾏快速排序。
    快速排序的⼀次划分从两头交替搜索,直到 low 和 high 指针重合,⼀趟时间复杂度 O(n),整个算法的时间复杂度与划分趟数有关。


    最好情况是每次划分选择的中间数恰好将当前序列等分,经过 log(n) 趟划分便可得到⻓度为 1 的⼦表, 这样时间复杂度 O(nlogn)。


    最坏情况是每次所选中间数是当前序列中的最⼤或最⼩元素,这使每次划分所得⼦表其中⼀个为空表   , 这样⻓度为 n 的数据表需要 n 趟划分,整个排序时间复杂度 O(n²)。


     
    Q17:循环和递归,你说下有什么不同的点?

     
    递归算法: 

    优点:代码少、简介。

    缺点:它的运行需要较多次数的函数调用,如果调用层数比较深,需要增加额外的堆栈处理,比如参数传递需要压栈等操作,会对执行效率有一定影响。但是,对于某些问题,如果不使用递归,那将是极端难看的代码。 

    循环算法:  

    优点:速度快,结构简单。

    缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环。

    Q18:排序算法怎么选择?


     
    数据量规模较⼩,考虑直接插⼊或直接选择。当元素分布有序时直接插⼊将⼤⼤减少⽐较和移动记录的次数,如果不要求稳定性,可以使⽤直接选择,效率略⾼于直接插⼊。


    数据量规模中等,选择希尔排序。


    数据量规模较⼤,考虑堆排序(元素分布接近正序或逆序)、快速排序(元素分布随机)和归并排序稳定性)。⼀般不使⽤冒泡。

    好了,整理结束,小伙伴们点赞、收藏、评论,一键三连走起呀,下期见~~

    最后,我将面试前用到的资料,都分享下,点击下面的,然后关注弹出的图,

    回复:csdn面试大全

    即可获取所有面试资料

    展开全文
  • 看Facebook工程师是怎么评价《第行代码》的

    万次阅读 多人点赞 2019-08-16 07:56:50
    虽然我最近几是在国外读书和工作的,但是和很多人一样,我也非常喜欢郭霖的博客以及他写的《第行代码——Android》。 事实上,这本书在我面试 Facebook 的时候给我提供了很大的帮助。为此,我专门为这本书写了...
  • 位10Java工作经验的架构师聊Java和工作经验

    万次阅读 多人点赞 2015-09-10 13:44:26
    黄勇( 博客),从事近十的 JavaEE 应用开发工作,现任阿里巴巴公司系统架构师。对分布式服务架构与大数据技术有深入研究,具有丰富的 B/S 架构开发经验与项目实战经验,擅长敏捷开发模式。国内开源软件推动...
  • 其中D是这个日子在这一年中的累积天数。算出来的W就是公元前1年(或公元0年)12月31日到这一天之间的间隔日数。把W用7除,余数是几,这一天就是星期几。比如我们来算2004年5月1日:  W = (2004-1)*365 + [(2004-1)/...
  • 可移植性:把程序从种硬件配置和(或)软件系统环境转移到另种配置和环境时,需要的工作量多少,有种定量度量的方法是:用原来程序设计和调试的成本除移植时需用的费用 可再用性:在其他应用该程序可以再次使用...
  • 31  “我们再重新找房吧?”伍定轩对段伏枥说道。    “为什么?”段伏枥突然觉得奇怪,为何伍定轩会突然提出这个问题。... 伍定轩继续说着:“你看,能够在恶劣的环境生存的仙人掌,居然在我们的屋子
  • 本文是我最近读书笔记的篇文章,主要是阅读《淘宝技术这十》的第部分,主要包括淘宝网的技术流程和基础介绍,希望文章对大家有所帮助,同时记录自己最近学习的内容。我似乎是2007初中看《赢在中国》的时候...
  • 81  对于新的4.3'CMMB板子来说,设计上并不是很难。毕竟之前有做过Telechips... 武总还是老样子,开始同意了,可没多久又像墙头草,又想将一些功能给添上去 。这回段伏枥和和曹燕就没打算妥协,因为大家都知道,
  • 手把手搭建一套简单的直播系统

    千次阅读 多人点赞 2020-02-29 23:12:08
    今天可是四年一遇的2.29,所以这次还是要写篇,纪念一下这个日子,顺便从当韭菜的身份,逃离出来。 本次用ngix+rtmp+ffmpeg搭建个流媒体服务器,实现简单的直播效果。 Nginx是款轻量级的Web 服务器/反...
  • 找工作季来了,互联网大潮也将至。近来陆续有不少师弟师妹校友求分享各种资料和经验,想来手头上...前面已经有找工作笔试面试那些事儿(15)---互联网公司面试的零零种种和多家经验、找工作笔试面试那些事儿(14)---轻松
  • MP4()-结构

    万次阅读 2013-12-09 14:47:11
    本文转载自网络,不过没找到原文在哪,感谢写这篇博文的哥们   、基本概念 1.mp4概述 MP4文件的所有数据都装在box...box可以包含另个box,这种box称为container box。个MP4文件首先会有且只有
  • 《疯狂的程序员》

    千次阅读 2012-10-25 20:31:54
    1 天已经七分黑了,屋里却还没开灯。这个全身黑衣服的男子突然像想起什么,从包里掏出烟,抽出一只,递给旁边的人:“兄弟,抽烟么?”――那烟是红塔山。...第一天到学校,其实没有一点新鲜的感觉
  • 我在创业游戏公司的一年

    千次阅读 多人点赞 2017-02-19 14:11:01
    一、写在前面的话从1512月入职到前两天离职,我经历了一个创业游戏公司的由盛到衰的整个过程,从16的下半年开始,每天上班就眼看着公司的状况一天不如一天。从另一方面来说,也算是映射了国内的大部分手游小团队...
  • 怎样成为个优秀的架构师?

    万次阅读 多人点赞 2019-10-08 17:15:37
    架构师是个既能掌控整体又能洞悉局部瓶颈并依据具体的业务场景给出解决方案的团队领导型人物。看似完美的“人格模型”背后,是艰辛的探索。 架构师不是个人,他需要建立高效卓越的体系,带领团队去攻城略地,在...
  • 所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十的编程经验分享给大家,希望对您有所帮助,文章不足之处也请海涵。在这个喧嚣的时代,很多技术或概念会不断兴起,我希望你能沉下心来去学习,不要...
  • 公元一年月一日为星期。这是标准定义,至于为什么这么定义,你可以去考证一下。  我们现在采用的立法是罗马教皇格里高利十三世修订“儒略历”所成的“格里历”,该历法规定自158210...4年一闰,称为“儒略历”
  • pmp每日

    万次阅读 2019-12-25 10:26:47
    2019.12.25 每日题: You are a project manager of a company and your project is currently in execution phase.The customer has requested you for additional work. This work will affect the budget, but ...
  • 、使用Sqoop抽取数据 ...它在20123月成功孵化,现在已是Apache的顶级项目。Sqoop有Sqoop1和Sqoop2两代,Sqoop1最后的稳定版本是1.4.6,Sqoop2最后版本是1.99.6。需要注意的是,1.99.6与1.4.6并不兼容,而且截止
  • python爬虫之:爬取网页小说(魂破九

    万次阅读 多人点赞 2018-04-28 02:52:27
    近期做个项目需要用到python,只懂皮毛的我花了三时间将python重新拾起啃啃,总算对python有了一定的认识。 然后有根据爬虫基本原理爬取了本小说,其他爬取小说的方法类似,结果见个人资源下载(本想下载分...
  • 20创业经历的咀嚼与反思,从战略、品牌、竞争,到流量、领导力、团队管理等,多角度多维度的重新认知,如李开复所言,“都是真刀真枪打出来的经验,值得每位创业者多读几遍,吸收内化”。 雷军、李开复、徐小平...
  • 这一年,这些书:2020读书笔记

    万次阅读 2021-01-29 08:06:08
    Note: 以下 markdown 格式文本由 json2md 自动转换生成,可参考JSON转Markdown:我把阅读数据从MongoDB导出转换为.md了了解具体的转换过程。 面纱 作者:毛姆[英] ISBN:9787210082835 出版社:江西人民出版社 ...
  • mysql5.7性能提升百倍调优宝典

    万次阅读 多人点赞 2020-05-06 10:07:36
    全文一共有常用的(事实上你如果花1-2周阅读、理解、自己动手设一下后是需要这么多参数的)76个参数,我是按照: 每个参数干吗? 在某些典型硬件配置下的db上参数该设多少? 设会怎么样? 不设会怎么样? ...
  • 货币的种互联网体系架构

    万次阅读 2019-05-10 10:50:30
    I. 介绍 中本聪最伟大的发明比特币,可以因为以下两处不同的特征广受赞誉: 比特币是公开的,去中心化的,加密总账(cryptographic ledger),同时拥有基本总账能力。 加密总账能追踪新的...这论文分析加密总...
  • 次作为面试官的感悟

    千次阅读 2017-09-29 22:42:48
    这几有幸跟着老员工经历了场校园招聘。遥想去年还是个小小求职者,现在就要坐在桌子的对面,角色的转变,还是感触良多,就简单记下来。最近半年绝少写博客了,第个原因当然是工作太忙了~ 显然,明白人都...
  • 场皆大欢喜的程序员跳槽事件

    万次阅读 多人点赞 2018-05-23 07:15:00
    A君在甲公司做了两多,这两多完成了一个大项目,作为开发的核心主力,开发压力很大,特别是项目上线前的几个月是非常辛苦,几乎每晚都要加班到12点以后,周末最多只有一天休息。 在最困难的时候,老板给大家大气...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 94,461
精华内容 37,784
关键字:

一年中最后一天被称为