精华内容
下载资源
问答
  • 因为CSDN,我人生进度条八分之一(年)的许多故事在这里书写,笔耕不辍,也算不得辜负时光吧;因为CSDN,我更珍惜每一位博友、每一位朋友、每一位老师,解答大家的问题,鼓励考研或找工作失败的人继续战斗;因为...

    从2010年我来到CSDN,再到2013年我撰写第一篇博客,转眼已经过去十年。590篇原创文章,786万次阅读量,19万位关注博友,这一个个数字的背后,是我3000多天的默默付出,也是我写下近千万文字的心血。

    有人说,世间一切,都是遇见,都是机缘。是啊,因为CSDN,我与很多人成为了好朋友,虽未谋面,但这种默默鼓励、相互分享的感觉真好;因为CSDN,我人生进度条八分之一(十年)的许多故事在这里书写,笔耕不辍,也算不得辜负时光吧;因为CSDN,我更珍惜每一位博友、每一位朋友、每一位老师,解答大家的问题,鼓励考研或找工作失败的人继续战斗;因为CSDN,我认识了女神,并分享了许多我们一家的故事。

    东西湖的夜很静,博士的征途很辛苦,远方的亲人异常思念。
    为什么我要写这样一篇文章呢?一方面,感谢读者这十年的陪伴和包容,不论我分享什么内容,你们给予我的都是鼓励和感动;另一方面,因为改变,接下来我将短暂告别CSDN一段时间(技术更新放缓),好好沉下心来去读论文,去做做科研。

    同时,这篇文章非常硬核,会利用Python文本挖掘详细分享这十年的故事,也算是为文本挖掘初学者和写相关论文的读者一些福利。真诚的对所有人说一声感谢,感恩这十年的陪伴,不负遇见,不负时光。请记住一个叫Eastmount的分享者,此生足矣~

    在这里插入图片描述


    一.忆往昔分享岁月

    关于作者与CSDN这十年的故事,可以阅读这篇文章:

    十年,转瞬即逝,我从青葱少年成长为了中年大叔。或许,对其他人来说写博客很平淡,但对我来说,它可能是我这十年最重要的决定和坚守之一。

    十年,不负遇见,不负自己,不负时光。感恩所有人的陪伴,因为有你们,人生路上我不孤单。幸好,这十年来,我可以摸着自己的良心说,每一篇博客我都在很认真的撰写,雕琢,都在用万字长文书写下我的满腔热血。

    下图是我这十年分享博客按月统计的数量,从2015年找工作分享一次高峰,到如今读博,从零学习安全知识并分享又是一座高峰。

    在这里插入图片描述

    下图是这十年我在CSDN撰写博客的主题演化图,整个十年,我经历了四个阶段。

    • 本科阶段:2013年3月至2014年8月
      当时以本科课程为主,包括C#、网络开发、课程基础知识等等。
    • 硕士阶段:2014年9月至2016年8月
      该阶段研究生方向为NLP和知识图谱,因此撰写了大量的Python基础知识,包括Android、C#、面试和LeetCode、网站开发等等。
    • 工作阶段:2016年9月至2019年7月
      该阶段作者初入职场,选择回到贵州当一名普通的大学教师,并分享了《Python数据挖掘》《网站开发》等课程,撰写《Python人工智能》《Python图像处理》等专栏。
    • 博士阶段:2019年9月至2021年4月
      该阶段作者再次返回校园,离别家乡亲人选择读博,并换了大方向,转而学习系统安全和网络安全,大量安全知识从零学起,《网络安全自学篇》《网络安全提高班》《系统安全和恶意代码检测》专栏也开启。

    在这里插入图片描述

    有许多人问我,“你分享快乐吗?”
    快乐。其实每写一篇博客我的内心都非常喜悦的,每看到读者的一个点赞或评论,我真的开心得像一个小孩。

    那为什么还要短暂消失呢?
    因为毕业,因为想家,因为想他(她)。我相信,大多数分享者都和我有同样的心情,分享知识的魅力让人久久不能忘怀。但每个阶段都需要做每个阶段的事,远方的亲人尤为思恋,经过我反复思考,所以我决定短暂放下技术博客的撰写,转而选择论文研究。

    在这里插入图片描述

    短暂的消失,并不意味着不分享。
    而接下来90%的分享都将与论文和科研技术相关,并且每个月不再PUSH自己写文。我不知道接下来的几年,我究竟能做到什么程度,我也不能保证能否发一篇高质量的论文,但我会去拼搏,会去战斗,会去享受。况且,这十年走来,我从来不认为自己是个聪明的人,比我优秀的人太多太多,我更喜欢的是默默撰写,默默经历,陪着大家一起成长。别人称赞我博客的时候,我更多的回复是“都是时间熬出来的”,也确实是时间熬出来的,只是写了3012天。

    但我是真的享受啊,享受在CSDN所分享的一切,享受与每一位博友的相遇相识,享受每一位朋友的祝福与鼓励,我感恩的写下590篇文章,65个专栏,千万文字和代码,也勉强可以说上一句“不负遇见,不负青春,此生足矣”。

    在这里插入图片描述

    在这里插入图片描述

    下图展示了这十年我写的博客涉及的各个方向。这些年,我一直都知道学得太杂,而没有深入,就希望博士期间能深入某个领域,博一博二安全基础知识也学了很多,所以接下来是时候进入第五个阶段,开启论文的阅读和撰写以及实验复现。也希望博友们理解,更期待您的陪伴。

    在这里插入图片描述

    沙子是握不住的,时间也是。
    但当我付出之后,我可以随手把它扬起,我可以把在时间中发生的点滴记录,比如技术、又如爱情。读博苦吗?苦,无数个寂静的夜都需要我们去熬,去拼,但有的人更苦,比如家里的另一位。接下来三年,我希望自己始终记住,我为什么选择来到这里,选择来到东西湖。也是时候沉下心来去学习论文和做实验了,技术分享该放就放,虽然不舍。握不住的沙,就随手扬了它;即便回到原点,我也没有失去什么,况且这段经历也是人生的谈资啊。也希望每一位博友都珍惜当下,都去做自己喜欢的事情,去经历。

    在这里插入图片描述

    我看着路,梦的入口有点窄,这或许是最美丽的意外。
    这篇文章我将使用在CSDN的第一次群发,还请见谅,下一次应该是2024年我博士毕业那天。再次感谢所有人的陪伴,一个好的分享者需要不断去学习新知识,前沿技术再总结给大家,所以我们应该尊重每一位创作者的果实。同时,我在这里向所有读者保证,三年之后,我将带着新的理解,新的感受,去分享更优质的文章,去回馈所有读者,帮助更多初学者入门,或许手痒我也会写一篇非常详细的总结吧。

    再次感谢大家,希望大家记住CSDN有一位叫Eastmount的作者,一位叫杨秀璋的博主,如果能记住娜璋和小珞一家就更开心了,哈哈~爱你们喔,困惑或遇到困难的读者,可以加我微信共同前行。

    在这里插入图片描述

    我们的故事都还在续写,你们的陪伴依然继续。
    最后,熟悉我的读者知道我开了三个付费专栏。常常有读者因在校读书或经济拮据,因此我在文中多次提到可以私聊我给全文,其实我早已把这些文章开源到了github,我更希望每一位读者都能从文章中学到知识,希望觉得文章好且手里轻松的给个9块打赏,奶粉钱就够了。在此,我也把这三个地址分享给需要的读者吧!且行且珍惜,购买也欢迎喔。

    • Python图像处理
      https://github.com/eastmountyxz/CSDNBlog-ImageProcessing
    • 网络安全自学篇
      https://github.com/eastmountyxz/CSDNBlog-Security-Based
    • Python人工智能
      https://github.com/eastmountyxz/CSDNBlog-AI-for-Python

    在这里插入图片描述

    给想学技术的说声抱歉,大家记得等我喔!江湖再见,感恩同行。

    在这里插入图片描述



    二.硬核-CSDN博客文本挖掘

    之前我给学安全的读者一波福利,告诉大家安全学习路线及CSDN优秀的博主。

    这里,我最后再给Python文本挖掘读者一波福利。希望您喜欢~这篇文章思路大家可以借鉴,但不要直接拿去写论文喔!但思路已经非常清晰,大家一定动手撰写代码。

    1.数据爬取

    这里不介绍具体代码,保护CSDN原创,但会给出对应的核心知识点。建议读者结合自己的方向去抓取文本知识。

    核心扩展包:

    • import requests
    • from lxml import etree
    • import csv

    核心流程:

    • 解决headers问题
    • 解决翻页问题
    • 审查元素分析DOM树结构
    • 定位节点采用Xpath分析
    • 分别赚取标题、URL、时间、阅读和评论数量
    • 详情页面抓取

    在这里插入图片描述

    在这里插入图片描述

    爬虫输出结果,建议学会打桩输出(多用print)。

    在这里插入图片描述

    整理后的结果如下图所示,内容输出到CSV存储。

    在这里插入图片描述


    2.计量统计和可视化分析

    (1) 按小时分析作者撰写习惯
    首先,我们来分析作者“Eastmount”的撰写博客习惯,同时利用Matplotlib和PyEcharts绘制图形,发现Echarts绘制的图形更好看。由图可知,该作者长期在深夜和下午撰写博客。

    在这里插入图片描述

    源代码如下:

    # encoding:utf-8
    """
    By:Easmount CSDN 2021-04-19
    """
    import re
    import time
    import csv
    import pandas as pd
    import numpy as np
    
    #------------------------------------------------------------------------------
    #第一步 读取数据
    dd = []   #日期
    tt = []   #时间
    with open("data.csv", "r", encoding="utf8") as csvfile:
        csv_reader = csv.reader(csvfile)
        k = 0
        for row in csv_reader:
            if k==0:      #跳过标题
                k = k + 1
                continue
            #获取数据 2021-04-08 21:52:21
            value_date = row[4]
            value_time = row[5]
            hour = value_time.split(":")[0]
            hour = int(hour)
            dd.append(row[4])
            tt.append(hour)
            #print(row[4],row[5])
            #print(hour)
            k = k + 1
    print(len(tt),len(dd))
    print(dd)
    print(tt)
    
    #------------------------------------------------------------------------------
    #第二步 统计不同小时的个数
    from collections import Counter
    cnt = Counter(tt)
    print(cnt.items())  #dict_items
    #字典按键排序
    list_time = []
    list_tnum = []
    for i in sorted(cnt):
        print(i,cnt[i])
        list_time.append(i)
        list_tnum.append(cnt[i])
    
    #------------------------------------------------------------------------------
    #第三步 绘制柱状图
    import matplotlib.pyplot as plt
    N = 24
    ind = np.arange(N)
    width=0.35
    plt.bar(ind, list_tnum, width, color='r', label='hour') 
    plt.xticks(ind+width/2, list_time, rotation=40) 
    plt.title("The Eastmount's blog is distributed by the hour")  
    plt.xlabel('hour')  
    plt.ylabel('numbers')  
    plt.savefig('Eastmount-01.png',dpi=400)  
    plt.show()
    
    #------------------------------------------------------------------------------
    #第四步 PyEcharts绘制柱状图
    
    from pyecharts import options as opts
    from pyecharts.charts import Bar
    bar=(
        Bar()
            .add_xaxis(list_time)
            .add_yaxis("数量", list_tnum, color="blue")
            .set_global_opts(title_opts=opts.TitleOpts(
                title="Eastmount博客按小时分布", subtitle="hour"))
        )
    bar.render('01-Eastmount博客按小时分布.html')
    

    (2) 按月份统计博客
    作者按月份撰写博客如下图所示,2015年找工作撰写了大量LeetCode代码,后续是读博期间安全分享较多。

    在这里插入图片描述

    源代码如下:

    # encoding:utf-8
    """
    By:Easmount CSDN 2021-04-19
    """
    import re
    import time
    import csv
    import pandas as pd
    import numpy as np
    
    #------------------------------------------------------------------------------
    #第一步 读取数据
    dd = []   #日期
    tt = []   #时间
    with open("data.csv", "r", encoding="utf8") as csvfile:
        csv_reader = csv.reader(csvfile)
        k = 0
        for row in csv_reader:
            if k==0:      #跳过标题
                k = k + 1
                continue
            #获取数据 2021-04-08 21:52:21
            value_date = row[4]
            value_time = row[5]
            hour = value_time.split(":")[0]   #获取小时
            hour = int(hour)
            month = value_date[:7]            #获取月份
            dd.append(month)
            tt.append(hour)
            #print(row[4],row[5])
            #print(hour,month)
            print(month)
            k = k + 1
            #break
    print(len(tt),len(dd))
    print(dd)
    print(tt)
    
    #------------------------------------------------------------------------------
    #第二步 统计不同日期的个数
    from collections import Counter
    cnt = Counter(dd)
    print(cnt.items())  #dict_items
    #字典按键排序
    list_date = []
    list_dnum = []
    for i in sorted(cnt):
        print(i,cnt[i])
        list_date.append(i)
        list_dnum.append(cnt[i])
    
    #------------------------------------------------------------------------------
    #第三步 PyEcharts绘制柱状图
    from pyecharts import options as opts
    from pyecharts.charts import Bar
    from pyecharts.charts import Line
    from pyecharts.commons.utils import JsCode
    
    line = (
        Line()
        .add_xaxis(list_date)
        .add_yaxis('数量', list_dnum, is_smooth=True,
                   markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]),
                   markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max"),
                                                           opts.MarkPointItem(type_="min")]))
        # 隐藏数字 设置面积
        .set_series_opts(
            areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
            label_opts=opts.LabelOpts(is_show=False))
        # 设置x轴标签旋转角度
        .set_global_opts(xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-30)), 
                         yaxis_opts=opts.AxisOpts(name='数量', min_=3), 
                         title_opts=opts.TitleOpts(title='Eastmount博客按日期分布'))        
        )
    line.render('02-Eastmount博客按日期分布.html')
    

    (3) 按星期统计博客
    按星期统计如下,调用date.weekday()函数可以输出对应的星期。周末作者更新稍微少一些。

    在这里插入图片描述

    核心代码如下:

    # encoding:utf-8
    """
    By:Easmount CSDN 2021-04-19
    """
    import re
    import time
    import csv
    import pandas as pd
    import numpy as np
    import datetime
    
    #定义星期函数
    def get_week_day(date):
        week_day_dict = {
            0 : '星期一',
            1 : '星期二',
            2 : '星期三',
            3 : '星期四',
            4 : '星期五',
            5 : '星期六',
            6 : '星期天'
        }
        day = date.weekday()
        return week_day_dict[day]
    
    #------------------------------------------------------------------------------
    #第一步 读取数据
    
    dd = []   #日期
    tt = []   #时间
    ww = []   #星期
    with open("data.csv", "r", encoding="utf8") as csvfile:
        csv_reader = csv.reader(csvfile)
        k = 0
        for row in csv_reader:
            if k==0:      #跳过标题
                k = k + 1
                continue
            #获取数据 2021-04-08 21:52:21
            value_date = row[4]
            value_time = row[5]
            hour = value_time.split(":")[0]   #获取小时
            hour = int(hour)
            month = value_date[:7]            #获取月份
            dd.append(month)
            tt.append(hour)
    
            #获取星期
            date = datetime.datetime.strptime(value_date, '%Y-%m-%d').date()
            week = get_week_day(date)
            ww.append(week)
            #print(date,week)
            k = k + 1
    print(len(tt),len(dd),len(ww))
    print(dd)
    print(tt)
    print(ww)
    
    #------------------------------------------------------------------------------
    #第二步 统计不同日期的个数
    from collections import Counter
    cnt = Counter(ww)
    print(cnt.items())  #dict_items
    #字典按键排序
    list_date = ['星期一','星期二','星期三','星期四','星期五','星期六','星期天']
    list_dnum = [0,0,0,0,0,0,0]
    
    for key,value in cnt.items():
        k = 0
        while k<len(list_date):
            if key==list_date[k]:
                list_dnum[k] = value
                break
            k = k + 1
    print(list_date,list_dnum)
    
    #------------------------------------------------------------------------------
    #第三步 PyEcharts绘制柱状图
    from pyecharts import options as opts
    from pyecharts.charts import Bar
    from pyecharts.charts import Line
    from pyecharts.commons.utils import JsCode
    bar=(
        Bar()
            .add_xaxis(list_date)
            .add_yaxis("数量", list_dnum, color='pink')
            .set_global_opts(title_opts=opts.TitleOpts(
                title="Eastmount博客按星期分布", subtitle="week"))
        )
    bar.render('03-Eastmount博客按星期分布.html')
    

    3.核心词统计及词云分析

    词云分析非常适合初学者,这里作者也简单分享核心主题词统计和词云分析的过程。

    (1) 统计核心关键词及词频
    输出结果如下图所示:

    在这里插入图片描述

    代码如下:

    # coding=utf-8
    """
    By:Easmount CSDN 2021-04-19
    """
    import jieba
    import re
    import time
    import csv
    from collections import Counter
    
    #------------------------------------中文分词----------------------------------
    cut_words = ""
    all_words = ""
    stopwords = ["[", "]", ")", "(", ")", "(", "【", "】",
                 ".", "、", "-", "—", ":", ":", "《", "》",
                 "的", "和", "之", "及", "“", "”", "?", "?"]
    
    #导入自定义词典
    #jieba.load_userdict("dict.txt")
    
    f = open('06-data-fenci.txt', 'w')
    
    with open("data.csv", "r", encoding="utf8") as csvfile:
        csv_reader = csv.reader(csvfile)
        k = 0
        for row in csv_reader:
            if k==0:      #跳过标题
                k = k + 1
                continue
            #获取数据
            title = row[1]
            title = title.strip('\n')
            #print(title)
            #分词
            cut_words = ""
            seg_list = jieba.cut(title,cut_all=False)
            for seg in seg_list:
                if seg not in stopwords:
                    cut_words += seg + " "
            #cut_words = (" ".join(seg_list))
            f.write(cut_words+"\n")
            all_words += cut_words
            k = k + 1
    f.close()
    #输出结果
    all_words = all_words.split()
    print(all_words)
    
    #------------------------------------词频统计---------------------------------- 
    c = Counter()
    for x in all_words:
        if len(x)>1 and x != '\r\n':
            c[x] += 1
    #输出词频最高的前10个词
    print('\n词频统计结果:')
    for (k,v) in c.most_common(10):
        print("%s:%d"%(k,v))
    #存储数据
    name ="06-data-word.csv"
    fw = open(name, 'w', encoding='utf-8')
    i = 1
    for (k,v) in c.most_common(len(c)):
        fw.write(str(i)+','+str(k)+','+str(v)+'\n')
        i = i + 1
    else:
        print("Over write file!")
        fw.close()
    

    (2) PyEcharts词云可视化
    输出结果如下图所示,出现词频越高的单词显示越大、越鲜艳。

    在这里插入图片描述

    代码如下:

    # coding=utf-8
    """
    By:Easmount CSDN 2021-04-19
    """
    import jieba
    import re
    import time
    import csv
    from collections import Counter
    
    #------------------------------------中文分词----------------------------------
    cut_words = ""
    all_words = ""
    stopwords = ["[", "]", ")", "(", ")", "(", "【", "】",
                 "01", "02", "03", "04", "05", "06", "07",
                 "08", "09", "什么"]
    f = open('06-data-fenci.txt', 'w')
    
    with open("data.csv", "r", encoding="utf8") as csvfile:
        csv_reader = csv.reader(csvfile)
        k = 0
        for row in csv_reader:
            if k==0:      #跳过标题
                k = k + 1
                continue
            #获取数据
            title = row[1]
            title = title.strip('\n')
            #print(title)
            #分词
            cut_words = ""
            seg_list = jieba.cut(title,cut_all=False)
            for seg in seg_list:
                if seg not in stopwords:
                    cut_words += seg + " "
            #cut_words = (" ".join(seg_list))
            f.write(cut_words+"\n")
            all_words += cut_words
            k = k + 1
    f.close()
    #输出结果
    all_words = all_words.split()
    print(all_words)
    
    #------------------------------------词频统计---------------------------------- 
    c = Counter()
    for x in all_words:
        if len(x)>1 and x != '\r\n':
            c[x] += 1
    #输出词频最高的前10个词
    print('\n词频统计结果:')
    for (k,v) in c.most_common(10):
        print("%s:%d"%(k,v))
    #存储数据
    name ="06-data-word.csv"
    fw = open(name, 'w', encoding='utf-8')
    i = 1
    for (k,v) in c.most_common(len(c)):
        fw.write(str(i)+','+str(k)+','+str(v)+'\n')
        i = i + 1
    else:
        print("Over write file!")
        fw.close()
    
    #------------------------------------词云分析----------------------------------
    from pyecharts import options as opts
    from pyecharts.charts import WordCloud
    from pyecharts.globals import SymbolType
    
    # 生成数据 word = [('A',10), ('B',9), ('C',8)] 列表+Tuple
    words = []
    for (k,v) in c.most_common(200):
        # print(k, v)
        words.append((k,v))
    # 渲染图
    def wordcloud_base() -> WordCloud:
        c = (
            WordCloud()
            .add("", words, word_size_range=[20, 40], shape='diamond') #shape=SymbolType.ROUND_RECT
            .set_global_opts(title_opts=opts.TitleOpts(title='Eastmount十年博客词云图'))
        )
        return c
    
    # 生成图
    wordcloud_base().render('05-Eastmount十年博客词云图.html')
    

    4.LDA主题挖掘

    LDA模型是文本挖掘或主题挖掘中非常经典的算法,读者可以阅读作者之前的文章,详细介绍该模型。这里,我们用它来对作者博客进行主题挖掘,设置的主题数为4,通常需要计算困惑度比较。

    在这里插入图片描述

    同时计算各个主题对应的主题词,如下所示。注意,建议读者结合自己的文本进行相应的优化,这会得到更符合真实情况的主题词,并且主题之间会存在相互交融的现象,比如安全系列博客,会有Python相关的渗透文章。

    在这里插入图片描述

    完整代码如下:

    #coding: utf-8
    import pandas as pd
    from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
    
    #---------------------  第一步 读取数据(已分词)  ----------------------
    corpus = []
    
    # 读取预料 一行预料为一个文档
    for line in open('06-data-fenci.txt', 'r').readlines():
        corpus.append(line.strip())
            
    #-----------------------  第二步 计算TF-IDF值  ----------------------- 
    # 设置特征数
    n_features = 2000
    tf_vectorizer = TfidfVectorizer(strip_accents = 'unicode',
                                    max_features=n_features,
                                    stop_words=['的','或','等','是','有','之','与','可以','还是','这里',
                                                '一个','和','也','被','吗','于','中','最','但是','大家',
                                                '一下','几天','200','还有','一看','300','50','哈哈哈哈',
                                                 '“','”','。',',','?','、',';','怎么','本来','发现',
                                                 'and','in','of','the','我们','一直','真的','18','一次',
                                               '了','有些','已经','不是','这么','一一','一天','这个','这种',
                                               '一种','位于','之一','天空','没有','很多','有点','什么','五个',
                                               '特别'],
                                    max_df = 0.99,
                                    min_df = 0.002) #去除文档内出现几率过大或过小的词汇
    tf = tf_vectorizer.fit_transform(corpus)
    print(tf.shape)
    print(tf)
    
    #-------------------------  第三步 LDA分析  ------------------------ 
    from sklearn.decomposition import LatentDirichletAllocation
    # 设置主题数
    n_topics = 4
    lda = LatentDirichletAllocation(n_components=n_topics,
                                    max_iter=100,
                                    learning_method='online',
                                    learning_offset=50,
                                    random_state=0)
    lda.fit(tf)
    # 显示主题数 model.topic_word_
    print(lda.components_)
    # 几个主题就是几行 多少个关键词就是几列 
    print(lda.components_.shape)                         
    # 计算困惑度
    print(u'困惑度:')
    print(lda.perplexity(tf,sub_sampling = False))
    
    # 主题-关键词分布
    def print_top_words(model, tf_feature_names, n_top_words):
        for topic_idx,topic in enumerate(model.components_):  # lda.component相当于model.topic_word_
            print('Topic #%d:' % topic_idx)
            print(' '.join([tf_feature_names[i] for i in topic.argsort()[:-n_top_words-1:-1]]))
            print("")
    # 定义好函数之后 暂定每个主题输出前20个关键词
    n_top_words = 20                                       
    tf_feature_names = tf_vectorizer.get_feature_names()
    # 调用函数
    print_top_words(lda, tf_feature_names, n_top_words)
    
    #------------------------  第四步 可视化分析  ------------------------- 
    import pyLDAvis
    import pyLDAvis.sklearn
    
    #pyLDAvis.enable_notebook()
    data = pyLDAvis.sklearn.prepare(lda,tf,tf_vectorizer)
    print(data)
    #显示图形
    pyLDAvis.show(data)
    pyLDAvis.save_json(data,' 06-fileobj.html')
    

    5.层次聚类主题树状图

    层次聚类绘制的树状图,也是文本挖掘领域常用的技术,它会将各个领域相关的主题以树状的形式进行显示,这里输出结果如下图所示:

    在这里插入图片描述

    注意,这里作者可以通过设置过滤来显示树状图显示的主题词数量,并进行相关的对比实验,找到最优结果。

    # -*- coding: utf-8 -*-
    import os
    import codecs
    from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
    from sklearn.manifold import TSNE
    from sklearn.cluster import KMeans
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import jieba
    from sklearn import metrics
    from sklearn.metrics import silhouette_score
    from array import array
    from numpy import *
    from pylab import mpl
    from sklearn.metrics.pairwise import cosine_similarity
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    from scipy.cluster.hierarchy import ward, dendrogram
    
    #---------------------------------------加载语料-------------------------------------
    text = open('06-data-fenci.txt').read()
    print(text)
    list1=text.split("\n")
    print(list1)
    print(list1[0])
    print(list1[1])
    mytext_list=list1
    
    #控制显示数量
    count_vec = CountVectorizer(min_df=20, max_df=1000)  #最大值忽略
    xx1 = count_vec.fit_transform(list1).toarray()
    word=count_vec.get_feature_names() 
    print("word feature length: {}".format(len(word)))
    print(word)
    print(xx1)
    print(type(xx1))
    print(xx1.shape)
    print(xx1[0])
    
    #---------------------------------------层次聚类-------------------------------------
    titles = word
    #dist = cosine_similarity(xx1)
    
    mpl.rcParams['font.sans-serif'] = ['SimHei']
    
    df = pd.DataFrame(xx1)
    print(df.corr())
    print(df.corr('spearman'))
    print(df.corr('kendall'))
    dist = df.corr()
    print (dist)
    print(type(dist))
    print(dist.shape)
    
    #define the linkage_matrix using ward clustering pre-computed distances
    linkage_matrix = ward(dist) 
    fig, ax = plt.subplots(figsize=(8, 12)) # set size
    ax = dendrogram(linkage_matrix, orientation="right",
                    p=20, labels=titles, leaf_font_size=12
                    ) #leaf_rotation=90., leaf_font_size=12.
    #show plot with tight layout
    plt.tight_layout() 
    #save figure as ward_clusters
    plt.savefig('07-KH.png', dpi=200)
    plt.show()
    

    6.社交网络分析

    社交网络分析常用于引文分析,文科领域有的成为文献知识图谱(和Google提出的知识图谱或本体有区别),它也是文献挖掘领域常用的技术手段。这里我们绘制社交网络关系图谱如下所示,主要利用Gephi软件,也推荐Neo4j或D3。可以看到作者十年的分享主要集中在四块内容,它们又相互联系,相辅相成。

    • 网络安全
    • Python
    • 逆向分析
    • 基础知识或编程技术

    推荐文章:

    在这里插入图片描述

    第一步,我们需要计算两两共现矩阵。数据量过大可能会边界溢出。
    输出结果如下图所示,此时希望大家进行停用词过滤或将异常关系删除。

    # -*- coding: utf-8 -*-
    """
    @author: eastmount CSDN 2020-04-20
    """
    import pandas as pd
    import numpy as np
    import codecs
    import networkx as nx
    import matplotlib.pyplot as plt
    import csv
    from scipy.sparse import coo_matrix
     
    #---------------------------第一步:读取数据-------------------------------
    word = [] #记录关键词
    f = open("06-data-fenci.txt", encoding='gbk')            
    line = f.readline()           
    while line:
        #print line
        line = line.replace("\n", "") #过滤换行
        line = line.strip('\n') 
        for n in line.split(' '):
            #print n
            if n not in word:
                word.append(n)
        line = f.readline()
    f.close()
    print(len(word)) #关键词总数 2913
    
    #--------------------------第二步 计算共现矩阵----------------------------
    a = np.zeros([2,3])
    print(a)
    
    #共现矩阵
    #word_vector = np.zeros([len(word),len(word)], dtype='float16')
    
    #MemoryError:矩阵过大汇报内存错误 采用coo_matrix函数解决该问题
    print(len(word))
    #类型<type 'numpy.ndarray'>
    word_vector = coo_matrix((len(word),len(word)), dtype=np.int8).toarray() 
    print(word_vector.shape)
    
    f = open("06-data-fenci.txt", encoding='gbk')  
    line = f.readline()           
    while line:
        line = line.replace("\n", "") #过滤换行
        line = line.strip('\n') #过滤换行
        nums = line.split(' ')
    
        #循环遍历关键词所在位置 设置word_vector计数
        i = 0
        j = 0
        while i<len(nums):         #ABCD共现 AB AC AD BC BD CD加1
            j = i + 1
            w1 = nums[i]           #第一个单词
            while j<len(nums):
                w2 = nums[j]       #第二个单词
                #从word数组中找到单词对应的下标
                k = 0
                n1 = 0
                while k<len(word):
                    if w1==word[k]:
                        n1 = k
                        break
                    k = k +1
                #寻找第二个关键字位置
                k = 0
                n2 = 0
                while k<len(word):
                    if w2==word[k]:
                        n2 = k
                        break
                    k = k +1
                #重点: 词频矩阵赋值 只计算上三角
                if n1<=n2:
                    word_vector[n1][n2] = word_vector[n1][n2] + 1
                else:
                    word_vector[n2][n1] = word_vector[n2][n1] + 1
                #print(n1, n2, w1, w2)
                j = j + 1
            i = i + 1
        #读取新内容
        line = f.readline()
        #print("next line")
    f.close()
    print("over computer")
    
    
    #--------------------------第三步  CSV文件写入--------------------------
    c = open("word-word-weight.csv","w", encoding='utf-8', newline='')    #解决空行
    #c.write(codecs.BOM_UTF8)                                 #防止乱码
    writer = csv.writer(c)                                    #写入对象
    writer.writerow(['Word1', 'Word2', 'Weight'])
    
    i = 0
    while i<len(word):
        w1 = word[i]
        j = 0 
        while j<len(word):
            w2 = word[j]
            #判断两个词是否共现 共现词频不为0的写入文件
            if word_vector[i][j]>0:
                #写入文件
                templist = []
                templist.append(w1)
                templist.append(w2)
                templist.append(str(int(word_vector[i][j])))
                #print templist
                writer.writerow(templist)
            j = j + 1
        i = i + 1
    c.close()
    

    第二步,我们需要构建实体(节点)和关系(边)的CSV文件。如下图所示:

    • entity-clean.csv
    • rela-clean.csv

    在这里插入图片描述

    在这里插入图片描述

    第三步,新建工程,并选择“数据资料”,输入电子表格。导入节点表格,选择entity实体表。

    在这里插入图片描述

    第四步,导入数据,设置为“边表格”,注意CSV表格数据一定设置为 Source(起始点)、Target(目标点)、Weight(权重),这个必须和Gephi格式一致,否则导入数据会提示错误。

    在这里插入图片描述

    第五步,导入成功后点击“概览”显示如下所示,接着就是调整参数。

    在这里插入图片描述

    第六步,设置模块化,在右边统计中点击“运行”,设置模块性。同时设置平均路径长度,在右边统计中点击“运行”,设置边概述。

    在这里插入图片描述

    在这里插入图片描述

    第七步,重新设置节点属性。节点大小数值设定为“度”,最小值还是20,最大值还是120。节点颜色数值设定为“Modularity Class”,表示模块化。

    在这里插入图片描述

    第八步,在布局中选择“Fruchterman Reingold”。调整区、重力和速度。

    在这里插入图片描述

    第九步,点击预览。设置宋体字,显示标签,透明度调整为20,如下图所示。

    在这里插入图片描述

    第十步,图谱优化和调整。
    同时可以过滤权重或设置颜色模块浅色。比如得到更为精细的关系图谱。

    在这里插入图片描述


    7.博客情感分析

    情感分析主要采用SnowNLP实验,也推荐大家使用大连理工大学情感词典进行优化。这里推荐作者之前分析的文章。输出结果如下图所示:

    在这里插入图片描述

    但是如果我们计算每天或每月新闻的总体情感分数,就会达到时间序列的情感分析图,从而更好地对情感趋势进行预测,文本挖掘或图书情报领域中使用得也非常多。

    在这里插入图片描述

    # -*- coding: utf-8 -*-
    from snownlp import SnowNLP
    import codecs
    import os
    
    #获取情感分数
    source = open("06-data-fenci.txt", "r", encoding='gbk')
    fw = open("09-result.txt", "w", encoding="gbk")
    line = source.readlines()
    sentimentslist = []
    for i in line:
        s = SnowNLP(i)
        #print(s.sentiments)
        sentimentslist.append(s.sentiments)
    
    #区间转换为[-0.5, 0.5]
    result = []
    i = 0
    while i<len(sentimentslist):
        result.append(sentimentslist[i]-0.5)
        fw.write(str(sentimentslist[i]-0.5)+"\n")
        print(sentimentslist[i]-0.5, line[i].strip("\n"))
        i = i + 1
    fw.close()
    
    #可视化画图
    import matplotlib.pyplot as plt
    import numpy as np
    plt.plot(np.arange(0, 598, 1), result, 'k-')
    plt.xlabel('Number')
    plt.ylabel('Sentiment')
    plt.title('Analysis of Sentiments')
    plt.show()
    

    8.博客主题演化分析

    最后是主题化验研究,这里推荐大家阅读南大核心相关的论文。其实主题演化通常分为:

    • 主题新生
    • 主题消亡
    • 主题融合
    • 主题孤独

    主题融合的计算方法各种各样,大家可以寻找最适合自己论文的方法,比如词频、权重、O系数、关联性分析等等。这里推荐大家使用Echarts绘制,作者的图谱如下图所示:

    在这里插入图片描述

    注意,作者这里给出的代码是另一个案例。但原理一样,仅供参考。真实情况的计算过程更为复杂,计算演化系数通常为小数。

    option = {
        series: {
            type: 'sankey',
            layout:'none',
            focusNodeAdjacency: 'allEdges',
            data: [
            {
                name: 'T1-竞争情报'
            },{
                name: 'T1-企业'
            },{
                name: 'T1-企业管理'
            }, {
                name: 'T1-情报研究'
            },{
                name: 'T1-竞争对手'
            },{
                name: 'T1-情报工作'
            },{
                name: 'T1-市场经济'
            },{
                name: 'T2-竞争情报'
            },{
                name: 'T2-企业'
            },{
                name: 'T2-企业管理'
            },{
                name: 'T2-竞争情报系统'
            },{
                name: 'T2-竞争对手'
            },{
                name: 'T2-知识管理'
            },{
                name: 'T2-反竞争情报'
            },{
                name: 'T3-竞争情报'
            },{
                name: 'T3-企业'
            },{
                name: 'T3-竞争情报系统'
            },{
                name: 'T3-企业管理'
            },{
                name: 'T3-高校图书馆'
            },{
                name: 'T3-反竞争情报'
            },{
                name: 'T3-知识管理'
            },{
                name: 'T4-竞争情报'
            },{
                name: 'T4-企业'
            },{
                name: 'T4-大数据'
            },{
                name: 'T4-产业竞争情报'
            },{
                name: 'T4-竞争情报系统'
            },{
                name: 'T4-高校图书馆'
            },{
                name: 'T4-企业管理'
            }
            
            ],
            links: [{
                source: 'T1-竞争情报',
                target: 'T2-竞争情报',
                value: 10
            }, {
                source: 'T1-企业',
                target: 'T2-企业',
                value: 7
            }, {
                source: 'T1-企业管理',
                target: 'T2-企业管理',
                value: 6
            },{
                source: 'T1-情报研究',
                target: 'T2-竞争情报',
                value: 5
            },{
                source: 'T1-竞争对手',
                target: 'T2-竞争对手',
                value: 5
            },{
                source: 'T1-情报工作',
                target: 'T2-竞争情报',
                value: 3
            },{
                source: 'T1-市场经济',
                target: 'T2-竞争情报',
                value: 3
            },{
                source: 'T1-竞争情报',
                target: 'T2-竞争情报系统',
                value: 5
            },{
                source: 'T1-竞争情报',
                target: 'T2-竞争情报系统',
                value: 3
            },{
                source: 'T1-竞争情报',
                target: 'T2-知识管理',
                value: 3
            },{
                source: 'T1-竞争情报',
                target: 'T2-反竞争情报',
                value: 3
            },
            
            {
                source: 'T2-竞争情报',
                target: 'T3-竞争情报',
                value: 10
            },{
                source: 'T2-企业',
                target: 'T3-企业',
                value: 7
            },{
                source: 'T3-竞争情报系统',
                target: 'T4-竞争情报',
                value: 3
            },{
                source: 'T2-企业管理',
                target: 'T3-企业管理',
                value: 6
            },{
                source: 'T2-竞争情报系统',
                target: 'T3-竞争情报系统',
                value: 5
            },{
                source: 'T2-竞争对手',
                target: 'T3-竞争情报',
                value: 5
            },{
                source: 'T2-知识管理',
                target: 'T3-知识管理',
                value: 3
            },{
                source: 'T2-反竞争情报',
                target: 'T3-反竞争情报',
                value: 3
            },{
                source: 'T2-竞争情报',
                target: 'T3-高校图书馆',
                value: 4
            },
            
            {
                source: 'T3-竞争情报',
                target: 'T4-竞争情报',
                value: 10
            },{
                source: 'T3-企业',
                target: 'T4-企业',
                value: 7
            },{
                source: 'T3-竞争情报',
                target: 'T4-大数据',
                value: 5
            },{
                source: 'T3-竞争情报',
                target: 'T4-产业竞争情报',
                value: 5
            },{
                source: 'T3-竞争情报系统',
                target: 'T4-竞争情报系统',
                value: 6
            },{
                source: 'T3-企业管理',
                target: 'T4-企业管理',
                value: 4
            },
            {
                source: 'T3-高校图书馆',
                target: 'T4-高校图书馆',
                value: 4
            },{
                source: 'T3-反竞争情报',
                target: 'T4-竞争情报',
                value: 3
            },{
                source: 'T3-知识管理',
                target: 'T4-竞争情报',
                value: 2
            }
            
            ]
        }
    };
    

    运行截图如下所示:

    在这里插入图片描述


    9.拓展知识

    读者还可以进行各种各样的文本挖掘,比如:

    • 命名实体识别
    • 知识图谱构建
    • 智能问答处理
    • 舆情事件预测


    三.总结

    最后用我的博客签名结束这篇文章,“无知·乐观·低调·谦逊·生活”,时刻告诉自己:无知的我需要乐观的去求知,低调的底色是谦逊,而谦逊是源于对生活的通透,我们不止有工作、学习、编程,还要学会享受生活,人生何必走得这么匆忙,做几件开心的事,写几篇系统的文,携一位心爱的人,就很好!感恩CSDN,感谢你我的坚守和分享,这又何止是十年。

    感恩所有读者十年的陪伴,短暂消失只为更好的遇见。接下来三年,愿接纳真实的自己,不自卑,不自傲;愿踏踏实实努力、认认真真生活,爱我所爱,无怨无悔,江湖再见。欢迎大家留言喔,共勉~

    在这里插入图片描述

    (By:Eastmount 2021-04-28 晚上12点 http://blog.csdn.net/eastmount/ )


    展开全文
  • 重温C语言,这三十多个细节你把握住了?

    万次阅读 多人点赞 2021-05-31 21:29:38
    文章目录前言基本篇1、编写代码文档难度指数:1颗星 / 细节指数:5颗星 / 重要指数:5颗星...前天参加了软件设计师考试,说实话,有点emmm,但是我也发现很基础已经忘得差不多了,这就是传说中的手生了吗? 手生到什.

    在这里插入图片描述

    文章目录

    前言

    好久不见啦朋友们。

    前天参加了软件设计师考试,说实话,有点emmm,但是我也发现很多基础已经忘得差不多了,这就是传说中的手生了吗?
    手生到什么地步?前天晚上帮我朋友改代码,甚至连scanf输入double类型数据用什么方式我都想不起来了。

    所以,我就整理了一下我自己的学习路线。
    江东子弟多才俊,卷土重来未可知!

    拿着《C Primer Plus》梳理了一遍,发现还真的有不少细节平时没有注意到,或者是没有刻意的去注意。


    基本篇

    1、编写代码文档

    难度指数:1颗星 / 细节指数:5颗星 / 重要指数:5颗星

    (写代码不写文档,拖出去打屎)

    最开始接触到代码文档不知道是什么时候了,但是让我想写代码文档绝对是在pycharm上。
    很方便,打三个引号,一个回车,什么都给你准备好了。
    然后我就想在VS上也找到类似的功能。起初没找到,后来误打误撞试出来了:

    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="l1"></param>
            /// <param name="l2"></param>
            /// <returns></returns>
    

    呐,看明白不?画三个杠,不用回车,两个<summary>之间写你的函数功能描述,</param>之间写你的参数释义,也可以写在</param>后面,return我就不多说啥了吧。


    C语言相对其他语言的优势

    难度指数:1颗星 / 细节指数:1颗星 / 重要指数:3颗星

    (连C语言的优势都不清楚,学来干什么?)

    1、目前我们所学习的各种语言,基本都离不开C语言的影子,所谓万变不离其宗,就是这个道理。
    2、C语言快,不接受反驳。不要说什么汇编更快,写个我看看。
    3、可移植性强。就拿嵌入式这一块来说,哪个语言能轻松移植?
    4、细节把控到位。C语言给了程序员极大的细节操作权限,连内存分配都给了。只是我们自己把握不住而已,C语言的水太深了。


    C语言为什么不内置输入输出语句?

    难度指数:2颗星 / 细节指数:4颗星 / 重要指数:3颗星

    别说输入输出了,不包任何头文件,我不知道还能写什么C代码。

    为什么要这样呢?像Python那样都内置了不好吗?

    这也是C语言为什么能做嵌入式,而Python做不了的一个重要原因。

    C语言的一个基本设计原则是避免不必要的成分

    我们不可否认,并不是所有项目都需要输入输出的。


    儿童节快乐呀各位


    int main() 与 void main()的区别

    难度指数:1颗星 / 细节指数:3颗星 / 重要指数:2颗星

    不知道有多少小伙伴接触过这个 void main(),反正我刚开始学C的时候,那个老师是教我们写这个的,当时就跟我们说,如果没有什么返回值,就写这个就好啦。
    后来,遇到我的授业恩师的时候,他叫我们说,不要写void main()了,打开编辑器,写完头文件依赖之后,先把下面这个框架写上:

    int main(){
    	
    	return 0;
    }
    

    就算没有什么返回值,也写一个return 0;,错不了的。

    有些编译器会允许void main()的形式,但是还没有任何标准考虑接受它,所以编译器可以不接受这种形式,这就是一个在平台移植中存在的一个隐患。

    多写一行return 0;很难吗?


    可写可不写的花括号,凭什么要我写?

    难度指数:1颗星 / 细节指数:2颗星 / 重要指数:2颗星

    有的小伙伴可能不知道,在循环语句、分支语句中,如果代码块儿只有一行的情况下(或者循环下面只有一个分支语句),则那个花括号是可写可不写的。

    比方说:

    while(1)
    	printf('1\n')
    

    那这个花括号写不写呢?
    不写会有什么好处?
    1、代码看起来行数会短一丢丢
    2、少写两个括号

    不写有什么坏处?
    当下基本不会有什么坏处,当下咱的头脑坑定是清醒的,知道为什么不写。
    但是修改代码的时候呢?如果要在这种循环下动刀,却又忽略了这个括号呢?
    我前两天就遇到了,浪费我五分钟去调试。

    所以啊,又不是说什么很必要的,为什么不写?写两个括号会累着?


    0==aa==0

    难度指数:1颗星 / 细节指数:4颗星 / 重要指数:2颗星

    这个又属于那种举手之劳,但是暴雷的时候不知死活的问题了。

    一般这个细节老师在讲分支循环的时候都会说吧,如果少写了一个等号,0=a是会报错的,但是a=0是会崩溃的。

    不过现在还好,有的编辑器就会警告,前提是要使用够好的编辑器,碧如VS。
    像我以前用TXT编程的时候,这个问题就只能靠自己去挖掘了。

    细节之处见真章。


    T、‘T’、“T”的区别

    难度指数:3颗星 / 细节指数:2颗星 / 重要指数:4颗星

    这就涉及到字符和字符串的概念了。
    这也是一段时间不敲C代码会很容易忘掉的一个点。

    首先,T如果经过赋值,它既是一个变量。否则它什么也不是。
    其次,‘T’是一个字符,一个char,不是一个字符串。
    紧接着,“T”是一个字符串,不是一个char。

    什么是字符串,可以理解为char的数组,不过在字符串结尾的时候会带上一个‘\0’。


    short、long、unsigned

    难度指数:2颗星 / 细节指数:2颗星 / 重要指数:1颗星

    不要再觉得这三个很神秘了,它们只不过是修饰词而已了。

    short,可能占用比int类型更少的空间,用于仅需小数值的场合,可以简写为short。同int 类型一样,是一种有符号类型。

    long,可能占用比int类型更大的空间,用于使用大数值的场合,可简写为long。同int类型一样,是一种有符号类型。

    long long,可能占用比long更大的空间,用于更大数值的场合,可简写为long long,同int类型一样,是一种有符号类型。

    unsigned,用于只使用非负的场合。将原本分配给负数的空间大小都分配给了正数。


    标准输入输出中的占位符

    难度指数:2颗星 / 细节指数:2颗星 / 重要指数:3颗星

    %d —— 以带符号的十进制形式输出整数
    %o —— 以无符号的八进制形式输出整数
    %x —— 以无符号的十六进制形式输出整数
    %u —— 以无符号的十进制形式输出整数
    %c —— 以字符形式输出单个字符
    %s —— 输出字符串
    %f —— 以小数点形式输出单、双精度实数
    %e —— 以标准指数形式输出单、双精度实数
    %g —— 选用输出宽度较小的格式输出实数
    

    如果是打印short,用%u,打印long,用%ld,以免在移植过程中造成不必要的麻烦。


    scanf读取字符串

    和读取单个字符不同,读取字符串的时候,是不需要加上&符号的。


    常用ascii码

    难度指数:1颗星 / 细节指数:3颗星 / 重要指数:4颗星

    其实上网一搜就有了,但是有的比较重要的还是要记一下的。

    ESC -- 27
    0 -- 48
    A -- 65
    a -- 97
    

    浮点数的比较大小

    难度指数:1颗星 / 细节指数:2颗星 / 重要指数:2颗星

    对于浮点数的比较,只能用<和>,舍入误差可能造成两个逻辑上应该相等的数不相等。。


    在这里插入图片描述


    提升篇

    刷新输出

    难度指数:2颗星 / 细节指数:3颗星 / 重要指数:4颗星

    printf()什么时候真正把输出传送给屏幕?printf()语句将输出传送给一个被称为缓冲区的中介存储区域,缓冲区中的数据再不断地被传送给函数。

    标准C规定在以下情况下将缓冲区内容输送给屏幕:
    1、缓冲区满
    2、遇到换行符
    3、后面跟了一个scanf语句

    可能在平时看来没有什么关系,但是我们在写服务器代码的时候就会有这种问题出来,有时候会导致消息队列被卡死,有时候会导致数据无法及时的被排出。


    这里拓展一下缓冲区,为什么需要缓冲区?
    首先,将若干个字符作为一个块传输比逐个发送这些字符耗费的时间少。
    其次,如果输入有误,就可以使用回删来更正错误。
    当最终按下回车简单的时候,就可以发送正确的输入。

    缓冲分为两类,完全缓冲I/O和行缓冲I/O,对完全缓冲输入来说,缓冲区满时被清空,这种类型的缓冲常出现在文件传输中。缓冲区的大小取决于操作系统。
    对于行缓冲来说,遇到一个换行符就将清空缓冲区,键盘输入是标准的行缓冲,因此按下回车键将清空缓冲区。


    out of range

    难度指数:4颗星 / 细节指数:5颗星 / 重要指数:5颗星

    我就不吭声儿,哪个写C/C++的朋友没有遇到过这个问题。

    越界。

    一个潜在的问题是:出于执行速度考虑,C并不检查您是否使用了正确的数值下标,当程序运行的时候,这些语句把数据放在可能被其他数据使用到的位置上,因而可能破坏程序的结果,甚至使得程序结果崩溃。


    scanf 和 scanf_s

    难度指数:3颗星 / 细节指数:1颗星 / 重要指数:2颗星

    在使用VS的时候,会发现编译器不通过scanf,给的理由是不安全、即使已经#include<stdio.h>

    这时候,它就会推荐我们去使用scanf_s。

    解决方法一:
    点击项目->项目属性,点开属性页面
    在这里插入图片描述

    点击C/C++ -> 预处理器 -> 预处理器定义 -> 点击右侧的下拉列表 -> 点击下拉列表里的<编辑>
    在这里插入图片描述

    在预处理器定义中添加字段 _CRT_SECURE_NO_WARNINGS
    在这里插入图片描述

    然后点击确定,就可以使用scanf了

    但是仅限于这一个项目,其他的项目还是不能使用,因此需要对所有要使用scanf的项目进行逐个修改


    方法二:使用scanf_s

    scanf()不会检查输入边界,可能造成数据溢出。

    scanf_s()会进行边界检查。

    因为带“_s”后缀的函数是为了让原版函数更安全,传入一个和参数有关的大小值,避免引用到不存在的元素,防止hacker利用原版的不安全性(漏洞)黑掉系统。

    scanf_s()参数与scanf()不同:
    例如scanf_s(“%s”,&name,n),整形n为name类型的大小,如果name是数组,那n就是该数组的大小。


    char* 与 char[n]

    难度指数:1颗星 / 细节指数:3颗星 / 重要指数:3颗星

    这二者,最大的区别就在于,一个是动态空间分配,一个是静态空间分配。

    如果说,使用了char *a,这时候要使用a,要手动分配空间。

    而且,当我们使用sizeof(a)的时候,得出的结果是指针的大小,这是一个坑。

    要获取a的大小,使用len()函数。


    这里把后面一个问题一并写进来吧,

    结构体中是应该放 char* 还是char[] 呢?
    要知道,结构体不为字符串分配任何存储空间,所以自己掂量掂量。
    如果没有什么特殊需求,还是放char[],如果要定制,那就char*。
    反正这俩我都试过,一个是定长包,相对简单,一个是不定长包,虽然困难了点,可以克服。


    getchar() 与 putchar()

    难度指数:3颗星 / 细节指数:2颗星 / 重要指数:2颗星

    getchar的用法

    getchar()是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,也就是说,如果stdin有数据的话不用输入它就可以直接读取了,第一次getchar()时,确实需要人工的输入,但是如果你输了多个字符,以后的getchar()再执行时就会直接从缓冲区中读取了。
    实际上是 输入设备->内存缓冲区->程序getchar

    putchar的用法

    (1)输出:putchar函数只能用于单个字符的输出,向终端输出一个字符,且一次只能输出一个字符。
    (2)格式:对于变量来说,格式为:putchar(ch);对于常量来说,格式为:putchar(‘ch’),对于转义字符来说,格式为:putchar(’\n’)。


    sprintf()做字符串拼接

    难度指数:2颗星 / 细节指数:2颗星 / 重要指数:4颗星

    字符串的处理一直是很重要的问题,C语言中的字符串拼接又不像Python里面直接一个加号就能解决的。
    那么要怎么处理呢?这里采用 sprintf() 的方式来做这件事情。

    int sprintf(char *str, const char *format, ...);
    

    参数释义:

    str -- 这是指向一个字符数组的指针,该数组存储了 C 字符串。
    format -- 这是字符串,包含了要被写入到字符串 str 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。format 标签属性是 %[flags][width][.precision][length]specifier,具体讲解如下:
    

    不多说,上案例:

    char s[40]; 
    sprintf(s,"%s%d%c","test",1,'2'); /*第一个参数就是指向要写入的那个字符串的指针,剩下的就和printf()一样了
    

    设计原则:“需要知道”原则

    难度指数:3颗星 / 细节指数:4颗星 / 重要指数:4颗星

    为什么我觉得这个部分值得这么多星星呢?可能有的朋友觉得不值。
    写几个项目,再优化,就知道了。

    “需要知道”原则,类似于“单一职责原则”,尽可能保持每个函数内部工作对该函数的私密性,只共享那些需要共享的变量。


    作用域·链接

    难度指数:2颗星 / 细节指数:1颗星 / 重要指数:2颗星

    一个C变量具有以下链接之一:外部链接、内部链接或空链接。
    具有代码块作用域或者函数原型作用域的变量具有空链接,意味着它们是由其定义所在的代码块或函数原型所私有。

    重点来了:具有文件作用域的变量可能有内部链接或外部链接,一个具有外部链接的变量可以在一个多文件的程序的任何地方使用,一个具有内部链接的变量可以在一个文件的任何地方使用。

    那怎样知道一个文件作用域变量具有内部链接还是外部链接?可以看看在外部定义中是否使用了存储类说明符static。


    extern

    难度指数:2颗星 / 细节指数:2颗星 / 重要指数:3颗星

    把变量的定义声明放在所有函数之外,即创建了一个外部变量。为了使程序更加清晰,可以在使用外部变量的函数中通过使用extern关键字来再次声明它。

    如果变量是在别的文件中定义的,那么使用extern来声明该变量就是必须的。


    argc 和argv

    难度指数:2颗星 / 细节指数:2颗星 / 重要指数:3颗星

    在Linux底下编程的时候,经常会看到如下的一行代码:

    int main(int argc,char*argv[]){}
    

    有时候,这个argv还会在main函数实现中被用到,那么就会有小伙伴不知道是干嘛用的,或者说知道是干嘛用的,不知道怎么用。

    我也困惑过,所以写下来。

    main(int argc,char *argv[ ])
    
    argv为指针的指针
    
    argc为整数
    
    char **argv or: char *argv[] or: char argv[][]
    

    假设程序的名称为CX,

    当只输入CX,则由操作系统传来的参数为:

    argc=1,表示只有一程序名称。

    argc只有一个元素,argv[0]指向输入的程序路径及名称:./CX

    当输入==./CX CanShu_1==,有一个参数,则由操作系统传来的参数为:argc=2,表示除了程序名外还有一个参数。

    argv[0]指向输入的程序路径及名称。
    argv[1]指向参数para_1字符串。
    

    当输入==./CX CanShu_1 CanShu_2== 有2个参数,则由操作系统传来的参数为:argc=3,表示除了程序名外还有2个参数。

    argv[0]指向输入的程序路径及名称。
    
    argv[1]指向参数para_1字符串。
    
    argv[2]指向参数para_2字符串。
    

    以此类推.


    C/C++预编译/条件编译指令

    难度指数:2颗星 / 细节指数:2颗星 / 重要指数:3颗星

    实在不想再长篇大论了,偷个懒吧:讲通C/C++预编译/条件编译指令 #ifdef,#ifndef,#endif,#define,…


    指针篇

    难度指数:5颗星 / 细节指数:5颗星 / 重要指数:5颗星

    开发成长之路(3)-- C语言从入门到开发(讲明白指针和引用,链表很难吗?)

    精品专栏打造计划


    展开全文
  • 看几个机器推荐的内容不会觉得可惜,但错过了朋友们都在看的内容会觉得可惜。这是视频号能借助社交推荐起来的理由。 于是五月份开始了变更最频繁的两周,几乎每两天就要更新一个版本。然后发布了基于朋友点赞的...

    因为疫情,今年微信的公开课Pro和开发者倍加关注的微信之夜放到了线上举行,微信之父,腾讯高级执行副总裁、微信事业群总裁张小龙的微信之夜直播,更是用今天他在演讲中反复提及的视频号进行直播,将今天的活动推向高潮。

    在一个半小时的演讲中,张小龙把绝大部分时间花在了讲解视频号和直播上,因为在他看来,视频化表达将会成为下一个十年内容领域的主题。此外,他还透露了团队正在研发微信输入法、歌曲类实验性项目等未来微信关注的新动向。

    微信之夜上,被视为产品偶像的张小龙对微信还有哪些思考?在他的演讲实录中,我们可以仔细品味:

    各位朋友,晚上好!

    谢谢来到公开课现场的朋友们,让我感受到这是一个面对面的交流,而不是一个人面对屏幕的直播。

    2020,对很多人来说都是很不容易的一年。包括我们的公开课,也改为线上进行了。虽然在几年前的一次公开课上,我说公开课应该线上开就好了,效率最高,但没有想到今天是因为疫情的原因被迫做到了。

    去年这个时候我们也没有想到,这次我们已经通过视频号来进行直播了。

    在这里插入图片描述

    因为疫情,很多公司的年会都改线上了,所以这个时候,我的同事们正在努力给视频号直播加一个能力,就是只有白名单的人才能进入直播间的企业内直播,希望能给需要线上开年会的企业一些帮助吧。

    回头看十年前,当时的想法只是,希望有一个适合自己的通讯工具来用。于是就开始了微信的第一版。但当时绝对没有想到,十年后的微信会是现在这个样子。对此,我自己感觉特别幸运,我想我一定是那个被上帝选中的人,因为光靠个人努力是做不到这一点的。

    我分享一组数据吧,到今天,每天——

    有10.9亿用户打开微信,3.3亿用户进行了视频通话;
    有7.8亿用户进入朋友圈,1.2亿用户发表朋友圈,其中照片6.7亿张,短视频1亿条;
    有3.6亿用户读公众号文章,4亿用户使用小程序;

    还有很多,包括微信支付,企业微信,微信读书,搜索等,就不一一说了。如微信支付,它就像你以前的钱包一样,已经变成了生活常用品。而微信,也真的成为了“一个生活方式”。

    今天是公开课,应该有很多的创作者参与,所以,也在这里感谢微信平台的每一个创作者,公众号的,小程序的,视频号的创作者。因为你们的创作,让微信的生态充满活力。

    大家知道视频号今年的变化特别大。这里也想分享一下视频号的一些想法。

    视频号的起源

    可能在2017年吧,我跟公众号的团队说,我们现在公众号只适合少数人写长文章,但是大部分人写不了文章。我们应该在朋友圈下面加一个“非朋友圈”,只能发短文或者照片视频。

    但后来就不了了之了,确实是很大的工程。因为帐号体系可能都完全不同了,就完全是个新的比公众号还复杂的系统。

    随着时间的推移,视频化表达其实越来越成为普通人的习惯。来看几个数据,最近5年,用户每天发送的视频消息数量上升33倍,朋友圈视频发表数上升10倍。这时候,我们再思考短内容的时候,就会想,不应该基于短文字来做,而是应该基于视频化内容来做了。

    视频化表达应该是下一个十年的内容领域的一个主题。虽然我们并不清楚,文字还是视频才代表了人类文明的进步,但从个人表达,以及消费程度来说,时代正在往视频化表达方向发展。

    于是在2019年,我们组织了一个特别小的小团队,开始了视频号的开发。

    我们也没有问公司要什么资源专门去做,甚至没有在公司开会立项,就自己悄悄做了。我觉得这很微信风格啊,基本上微信做东西,都是成立小团队开始做起,而不是大规模的兵团作战。

    并且我说,我们要做,就一定要做成做大。这并不是公司给的任务,因为完成任务是枯燥无味的,并且会因此动作变形。应该说是我们要给自己一些挑战性的目标,不然工作会显得很无聊。

    视频号是什么?

    视频号是一个人人都可创作的短内容平台。

    所以它是公开领域的内容平台,就不能基于微信号来创作了。

    因此遇到的第一个问题是,需要有一种新的ID(身份)。长期以来,微信的最大价值是每个人的微信ID。比如微信支付能很顺畅,因为钱包跟着个人ID走,这是非常自然的。就像你现在只拿身份证也能取钱一样。但这个ID是通讯和社交领域的,因此是私密的。因此,微信的用户并不能公开对非好友说话。即便评论了,别人也无法联系你。这对于社交领域当然没有问题。但对于公开领域,需要新的身份。而在一个产品里,承担两个身份,其实是很有挑战的。

    而这个新的ID,还必须特别方便,不至于在各个场景里遇到身份的冲突。所以处理得不好,双ID会让系统变得非常复杂。比如你评论,就需要选择用哪个ID来评论。

    但是这个ID的意义又特别大,一旦走出这一步,意味着微信不再局限于社交领域,而是进入到公开信息领域。

    因此视频号的意义,与其说是视频,不如说是“号”。因为有了一个公开的号,意味着每个人都有了一个公开发声的身份。

    比如,直播,在视频号里做得很顺利。在视频号之前,我们是没法做直播的,最多做到群内直播,那还是属于群通信的范畴。但有了视频号这个ID,每个人可以迅速开通自己的直播。这里,ID才是基石。它可以承载视频内容,可以承载直播,可以承载小程序等。

    我记得当时有个方案是,每个进视频号的人要创建一个视频号ID,用这个ID来浏览和评论内容。我说不对,浏览者应该是微信身份,而不应该强迫每个人开一个新的身份才能看和评论。幸好当时选择了这样一条路径,不然就没有后来的社交推荐体系了。其实产品的迭代是由无数这样的选择组成的。

    ID还有一个重要的意义是针对机构的。

    大家知道PC时代每个机构都有一个官方网站。其实微信一直在寻找PC时代的“官方网站”的替代物。做公众号的时候,我们希望公众号就是一个机构比如企业的官网。做小程序的时候,我们希望小程序就是官网。现在,我们希望视频号是每个机构的官网。这是合理的,官网是需要进化的。所以未来视频号会承接一个机构的很多服务内容,并不局限于视频。比如一个企业的服务,可以通过小程序的方式,展示在视频号下面。

    所以我开玩笑说,如果有一天我们在每一个广告牌下面,都能看到广告主的视频号的二维码,那就说明视频号做成了想要的官网了。

    第一个版本其实只是搭建了这样一个ID体系。和公众号的很类似,但是比公众号的门槛低很多,普通微信用户可以立即开通它。

    内容表现上,只是一个简单的信息流,混合了关注的,朋友匿名点赞的,和系统推荐的内容在里面。

    但这样的效果并不好。因为是灰度,量不大,因此也吸引不到大量的创作者来贡献内容,因此推荐的内容也一般般。

    但即使如此,我们还是希望推荐的质量能够好起来。我们组建了三个做推荐算法的团队,每个团队十几个工程师。希望各自用不同方法去找到推荐的最优解。

    应该说我们在算法领域沉淀应该还是很深的,搜一搜背后是个几百工程师的搜索技术团队,同时我们自己研发的语音识别和机器翻译,都是国内的一流水准。对了,外界一直有人说我们的语音识别用的是第三方的技术,其实我们从未用过第三方的,一直都是我们自己研发的。现在微信里面的语音识别每天翻译的语音条目在五亿条以上。

    虽然搜索团队有很强的算法技术人员,但是,我还是把他们从搜索团队抽调出来进入到视频号团队来工作。因为闭环的小团队才能迅速迭代。

    推荐团队很努力,但头几个月的滚动特别困难,似乎陷入了死结,就是内容不好看就没有浏览量,就导致没有人贡献内容,所以推荐系统也推不出好内容,然后继续没有好的内容看。

    5月份的时候,我们做了视频号最重大的一个改变。因为经过几个月的灰度,表明在现有的内容下,基于机器推荐是走不通的。对比朋友点赞的内容,虽然当时朋友点赞还是匿名的,和机器推荐的内容来对比,我发现,机器推荐的远不如人工(或者说朋友)推荐的精彩。既然这样,就应该以实名点赞的社交推荐为主,机器推荐为辅。

    当时我给的理由是,我们所看的书,大部分是因为周围有人推荐而去看,而不是网上书店推荐的书。你少看几个机器推荐的内容不会觉得可惜,但错过了朋友们都在看的内容会觉得可惜。这是视频号能借助社交推荐起来的理由。

    于是五月份开始了变更最频繁的两周,几乎每两天就要更新一个版本。然后发布了基于朋友点赞的新的灰度版本,终于看到了上扬的数据,用户的留存非常高。

    所以6月视频号的用户到了一个量级。数字其实不重要,但对于一个内容形态的产品来说,一定量级的用户意味着解决了生死问题,即流量的循环起来了。

    这是一种典型的微信style的产品方法,即通过产品而非运营的方法,找到事情的撬动点,通过产品能力让事情运转起来。

    有这个用户基数说明生存下来了,这时候就可以开始做基础功能的完善了,比如直播能力等。没有过生死线的话,做再多功能也是白搭。

    在这里,是社交推荐发挥了作用,当时机器推荐的占比非常小,留存也非常低,我们也差点就放弃了机器推荐。但是,并不是说机器推荐没有用,而是要在内容丰富的情况下才能发挥作用。

    插一个小故事,6月份的时候,那时社交推荐的新版还在开发吧,我在黑板上写下一个断言:未来有一天,视频的播放量,关注,好友推荐,机器推荐的消耗比例,应该是1:2:10。即,一个人应该平均看10个关注的视频,20个朋友赞的视频,100个系统推荐的视频这样的比例。

    当时是这么解释的:

    内容分两种,一种是你需要花脑力去理解的知识性信息,是学习;一种是不需要花脑力的思维舒适区的消费类的信息,是娱乐。朋友赞是朋友强迫你去获取你未必感兴趣的知识性信息,属于学习类的;机器推荐,是系统投其所好而让你很舒服的浏览你喜欢的消费性信息,属于娱乐类的。关注里面两种信息都有。

    因为关注的东西你已经知道大概会是什么了,反而不会太有吸引力,因此是1。朋友赞虽然看起来累,但是不能错过,所以是2。而系统推荐,符合懒人原则,是大多数人都更容易消费且获得舒适感的信息,所以是10。

    但是我们现在的大盘数据,并不是这个比例。现在朋友赞产生的整体vv,是机器推荐的2倍。

    于是我让数据同事统计了一下,只拿有关注的用户来看。有关注的用户目前极少,属于活跃用户,所以代表了未来活跃用户的行为。前几天的数据是,有关注的用户,人均在三个tab产生的vv,差不多是1:2:9。拿到这个结果时我非常吃惊。它只是一种粗略的估计,并不是说预测特别准确,而是说我们做东西的习惯是,如果这样做,应该先推理出来一个结果,然后用数据去验证,才能检验方向是不是对的。

    我估计未来这个9还会变得更大。因为这是和内容丰富度相关的。

    说到这里,可能会有人说当机器推荐这个9变得越来越大,不是不符合用完即走吗。用完即走跟时间长短无关,跟效率有关。我们从来不会关注用户在微信里停留的时长,那不是我们的目标。当用户想要看内容的时候,不管是文章还是视频,如果他花了很多时间看,只能说明微信里面有很多值得看的内容,而不是要刻意去消耗他的时间。

    什么是视频

    过程中还解决了另一个问题,即究竟什么是视频的问题。

    说到视频,大家会想到手机相册里面的视频文件。就像朋友圈,只能上传相册的视频。我们也确实是通过这个方式,来希望朋友圈里的视频更多的是用户自己拍摄的视频。

    但视频文件其实是会消失的。

    从Windows转到苹果手机的用户,都会遇到一个问题,以前的文件和文件夹去哪里了。在iOS里,没有了文件的概念。文件被各个应用自己定义了。这是把文件应用化了,即文件不能脱离应用而存在,一旦脱离了,就是没有意义无法解释的数据。

    这是一种很好的观念。

    原始视频只是数据,它没法关联到其他信息,如创作者,观众数,评论等。它还需要存在本地,数据丢了就丢了。

    因此未来的视频应该是一种结构化数据。它存在云端,有所有的创作者信息,有观众的互动信息,能够很方便的分享。

    文字和视频等内容,存在的价值在于有人看到,也就是分享。而分享,如果还需要copy整个原始数据,是很落后的。分享应该只是一个链接的传递。

    这会让我反思,朋友圈里面上传视频,以后会一直用这种原始方式吗?

    所以在6月的时候,我们需要把视频号内容分享到朋友圈来,遇到一个问题,它应该长得像一个链接呢,还是像一个本地视频呢?其实是归类,它应该归类到文章链接,还是一个视频文件。我的答案是,云端化的结构化的视频,才是视频,本地的视频文件,反而是裸数据,是应该被淘汰的。所以你看到的朋友圈里的视频号的视频,和现在的本地视频的展现没什么区别。

    在这里,视频号是结构化的视频内容的载体。我相信以后微信里面流通的视频,越来越多的会以视频号视频的形式存在,而不是视频文件的方式。

    这种变化,其实在公众号体系里体现过一次。公众号是一个文章的载体。它让文章因为分享而变得有价值。并且,公众号定义了文章的展现形式,是所有的用户在阅读不同的文章时,能以一种相对一致的体验来阅读和互动。在我看来,这是对网页时代阅读体验的一次大的体验提升。

    不管是文章还是视频,他们存在的价值在于被人看到,或者说被分享。显然,文章和视频需要一个载体来传播。

    如果你能理解公众号对于文章分享的价值,那么,可以用同样的思路去理解视频号对于视频分享的价值。

    载体的含义还体现在,我们自己不做内容,也不会去买内容。我们不关注具体的内容是什么。我们只做内容的承载和传递。

    长视频和短视频

    我们也遇到了超过一分钟视频的问题。自然而然地,大家会认为长视频和短视频是两种东西,因此应该设计成两种不同的内容对象。

    中间有个版本确实是视频号有专门的长视频这一栏的,甚至长视频和短视频的评论点赞还是分开的。

    但如果仔细思考,在微信号体系里,是不应该做这种区分的。长短视频的区别只是消费的场景不一样。短视频适合碎片时间的连续消费,而长视频适合有一大段时间来看。

    对视频号来说,简化这个问题的方法,是把一分钟以内的视频是为短视频,一分钟以上的视频的开头一分钟视为这个视频的摘要或简介。我把它称为封面。这样的话,视频号不区分长视频短视频,但是又能兼容短视频的体验。

    关于长视频,我希望视频号逐渐积累越来越多的长视频,成为长视频的云端仓库。将来有一天,也许我们会提供一个检索或推荐入口,这样用户可以找到丰富的长视频内容。

    这个其实也是未来非常有想象力的。

    视频号和个人的关系

    视频号的初衷是让人人都能很容易通过视频化的方式去公开表达内容。但做产品的人都知道,让用户去发表内容去表达是最困难的。

    现阶段我们也并没有做到让很多人在视频号去发表自己的日常。但我们有个举措,让我们能看到希望。我们上线了将自己的视频号内容关联到自己的微信名片的功能。我们发现结果比预料的要好很多,到现在已经有非常多人在名片展示了自己的视频号内容,并且还在持续增长。这是个很好的趋势。

    这里有一个很有意思的话题,有的时候大家会觉得微信做东西特别保守。其实并不是保守,而是说很多东西是不对或不应该做的。举个例子,我们可以把视频号的内容挂在名片上,我们以前为什么不做一个类似这样的展示自己的一些精选的照片和视频的功能?我们内部讨论过好多次,因为很多人朋友圈设置了三天可见,越来越多了,我们打开名片有的时候几乎看不到东西。为什么不给他们提供一个可以把一些照片精选放在那里的功能,这样朋友进来至少可以看到一些。

    之前我们不愿意做这个功能是因为,一旦这样做了,你可能只是把你历史上最好的照片放到那里,永远就不去修改它了。这次我们愿意这样做是因为,如果你关联到你的视频号的内容,那它就是活的,因为你会不停地更新你的视频号内容,而不是说我选几个历史上最好的照片作为精美的装饰就永远不变了。

    毕竟,视频号希望的是人人都能表达,而不是只有网红和大v的表演。

    信息展现的方式

    信息展现形式一直是互联网产品里的最基础部分,也是争议最大的。这里说的是指对信息列表的展现形式。

    常见比如有瀑布流,通俗称呼的信息流,以及全屏。他们的区别是一屏里放多少条内容合适。全屏就是一屏只放一条内容。

    以我自己的经验来说,我把这些式样的选择总结为一个粗略的规律,就是——

    一屏里的内容条数,应当跟命中率成反比。

    命中率是指用户可能感兴趣的内容条数的比例。比如10个邮件,只有一个是我想要看的,命中率是10%。

    以朋友圈举例,因为你并不是要看每一个朋友发的内容的,所以命中率并不高,如果改为全屏,就是灾难。同时,如果你添加的好友越来越多,命中率还会降低,因此就更不能增加每条内容的显示面积。如果我们要增大显示面积,就必须提高命中率。但朋友圈的命中率是很难提高的,因为朋友圈的命中率取决于朋友跟你的关系,而非他发的内容,而我们很难知道你对哪个朋友更感兴趣。

    而往往关注内容越多的人,命中率就越低。所以公众号改版的时候,其实是一屏里的内容条数变少了,虽然带来了点击次数的减少,但关注多的人还是会抱怨,因为选择的难度增大了。但对于关注少的人,阅读量是上升了,因为只关注了几个号的话,命中率本来就高。后来我们在订阅号的顶部增加了常读号的展示,其实是提升了命中率。

    视频号的上半年,平台的内容丰富度不够,命中率是很低的。所以当时半屏式的信息流是合适的,一屏显示超过一项内容,用户有选择的余地。那时候如果直接上全屏,可能死的很快。到下半年,内容开始丰富了,命中率开始提高了。并且全屏对于单个视频的展现效果当然也会比半屏要好,我们开始灰度的切换到全屏模式。

    这里说个有意思的数据。我们把关注和机器推荐灰度切换到全屏,并且和没有灰度全屏的用户来对比观察。发现全屏后,关注tab的人均vv(video view,视频播放量)下降了,推荐tab的上升了。这应该可以推导出来,关注tab的命中率不够高,以至于全屏后带来了轻微的选择困难。

    我们在公众号里在给关注的号的内容做排序,以及在视频号里,也会通过算法对关注的内容做排序,也是为了提高命中率。特别是全屏之后,因为用户的选择余地是零了,更需要算法来做排序。

    直播

    互联网历史上,个人在公开领域的表达方式一直在演变。最早的时候,需要你会写HTML来做网页。后来有了博客,博客之后是微博这样的短文字。现在是图片和短视频。演变的方向是往更能被普通人生产和消费的方向去走的。所以会体现为更短更碎片化。

    所以我在想,还有什么内容形态是比短视频更能被更多人接受的。

    我觉得直播有这个机会。直播比短视频的生产更容易,是因为拍一段短视频是需要有内容准备的。而直播,是不需要准备内容的,它就是日常聊天。这是一个非常巨大的差别,直接降低了直播的门槛。这是一种轻松的表达,普通人也能够去生产出来,朋友也更愿意去消费。

    虽然直播已经发展了很多年,大家对直播的认知还是带货的领域,这是作为内容形态的方式来思考,就是个人表达的形态方面来思考的。

    所以,直播在未来有可能会成为一种很多人在用的个人表达方式。

    做一个未来的设想,很久以后,每个人的微信名片应该是活的,意思是,我打开你的名片,如果你刚好戴了一个可以直播的眼镜正在直播,那我就能直接看到你看到的东西。这可能是个人直播的终极形态。

    前不久有一场流星雨的直播,有超过100万人观看了,有点超出我们的意料了。因为,我们并没有做任何中心化的流量分发去推它,它自然就吸引了100万人。在这里,是社交推荐在发生作用,通过朋友圈,群聊等进行了人群的扩散。当然,在视频号和直播的入口里面,我们还是会用机器推荐来给用户推荐适合的直播。当直播多了以后,除了你的朋友,我们也希望系统能告诉你哪个直播值得你看一下,这是我们的机器推荐有更大的考验。但社交推荐,仍然会是非常重要的传播途径。

    其实我们现在还没有直播的入口,下一个版本可能就有了。我们现在有一个附近的直播和人,把它调一下,可能叫直播和附近。

    我们也在丰富直播电商的能力,包括直播里可以挂接到第三方的小程序。

    春节快到了,我们都习惯了在群里发红包抢红包来拜年了。但其实线下传统的拜年是走家串户面对面的行为。直播其实更能模拟出线下拜年这种传统方式。所以我们今年在直播这里也做了一点小小的东西,我们希望今年的春节能够有一些人通过直播的方式来拜年,那就特别好。

    关于创作者

    很多人会关心平台会给创作者什么样的支持。

    如上面提到的,我们更希望做视频的载体,并且让视频号成为个人和机构的官网。平台在这里的角色是连接,而不是做内容。但和以前的官网不一样的地方在于,微信体系里的官网,内容是能自己流通的。因此你不用太担心做了官网也没有人访问。我刚刚说到微信里集合了很多产品可能没法尝试的东西,比如说对于信息访问,我们可能会有关注关系可以获得,有搜索,有推荐,有系统推荐和社交传递这样一些方式,所以不用太担心自己的内容在这里没有人会看。

    刚开始我们去邀请一些明星进来,明星会说有没有签约费。我们的回答是,我们希望你进来,因为你应该经营自己的粉丝,最终你会实现盈利,但不会平台出面来购买内容。

    所以视频号这里,我们没有花一分钱去购买内容。将来也不想这么做。倒不是为了省钱,而是,当我们不花钱买内容的时候,创作者还愿意进来,才说明创作者能靠自己的努力获得回报,才说明我们建立了一个能自行运转起来的生态。同时,我相信普通人的创作力是巨大的,相反,购买的内容反而不一定能打动人。

    微信的历史上,我们一直不强调强运营,也是这个原因。系统和规则会比运营的效率高太多了。就像我们现在看到微信支付,其实已经覆盖面非常大,但是我们微信支付的人数并不算多,对于支付这样一个需要跟线下接触的行业来说,我们每个行业微信支付里可能就一两个人在负责整个行业。

    公众号的那一个slogan照样可以用在视频号上,再小的个体,也有自己的品牌。其实你现在放在视频号上也是很适用的。

    一些有趣的实验性项目

    我们也有一些有趣好玩的实验性项目在进行中。

    前面提到,做产品其实是个验证想法的过程。如果你脑袋里突然冒出一个想法,可能很不靠谱,但又似乎有意思。然后继续往深里去想,如果能经过很多次选择,最终能变为实现,就会体会到做产品的乐趣。

    我就经常会有一些异想天开的想法。比如,如果你能拍一下一个人的头像会怎么样,如果你能朝跟你聊天的朋友扔一个炸弹在屏幕上炸开吓他一跳会怎么样,如果你在听一首歌的时候能看到其他听歌的人眼前的画面会怎么样,如果你失眠的时候也能看到其他的失眠的人然后大家一起数羊会怎么样。

    甚至,如果给一个画布,每个人上去画一个点,如果有一千万人轮流去每人依次画一个点,到最后会不会形成一个图案?如果在没有组织的情况下,一千万人居然画出来一个图案,那又意味着什么?

    所有这些都是很有趣的事情。所以做产品绝不是枯燥无味的。虽然大多数想法都会是行不通的,但有少数的能行得通,就非常好了。

    这里,我就简单描述下微信新版本会有的几个功能。所有的功能在被用户实际验证之前,都不能说一定会受欢迎,但是只要思路的方向没有问题,就可以不断改进。有些功能也会经历灰度,完善了才放出来。所以不要抱以太高的期望。这里分享下这些好玩的功能的思考点。

    一个是表情。

    表情是表达方式中的一个基本元素。

    说到表达方式的基本元素,这让我想起拍一拍。很多人会不喜欢被拍,还有很多人因为误触而拍错了人很尴尬。但仍然有1.2亿人设置了拍一拍的尾巴,每天几千万人在用拍一拍。拍一拍也是表达的一种基本元素,并且不同于其他所有方式,它是模拟人类的现实生活中的行为动作,用最简单的一个身体动作来完成了一次信息传递。有次内部开会我开玩笑说,未来人们的生活会越来越线上化,人们会怀念这种古老的人和人之间的交互方式的。

    说回到表情。

    人们的表情反映出情绪越来越强烈了。以至于必须经常“裂开”了。

    我的想法可能比裂开更暴力。有一天我跟开发同学说,帮我做一个功能,我扔出一个炸弹,对方的屏幕就裂开来。当然,是动画效果的裂开,但要求很逼真。

    实现是可以的,但是真的当作一个表情功能的时候,还是会遇到很多坎。

    我说寻找基本元素,即这种表情必须是底层基础的,而不是一种特殊的。

    最终我们做到了。

    一个是状态。

    现在大家打开一个朋友的微信名片,往往除了名字头像,什么也看不到。朋友圈也很多人设置了时效。

    但事情不应该是这样的,每个名片,应该是活生生的才对。名片就是我们线上化生活的自己,它应该反映自己真实的状态。

    我们之前尝试用视频动态表达一个人的状态,但视频化表达在这个地方其实挺困难的,因为确实拍个视频让所有的好友看到,这个压力还是挺大的,所以视频动态不算成功,每天大概有100多万的人在发视频动态,我们也会把它升级一下。升级以后的话,我们希望走到视频的另外一面。以前我说以前每个人发文字是很困难的,其实有一个前提,发一段让很多人都看的文字是很困难的,其实自己随便说一句话其实并不困难,状态就是随便说一句话这样一个东西。所以我们会走到视频的另外一面,通过你随便说一句话,随便写几个字来表达自己的状态。

    并且,在某一时刻,一定还有其他的人跟你处在同一种状态里,你会希望看到他们。看到在打同一个游戏的人,同一个咖啡吧的人,同一个景点旅游的人等,甚至是,同一种心情的人。

    我一直认为,社交的本质是找到同类。

    状态,是用来给人看到的,最好还是给同类的人看到。

    所以这一次,我们基于简单的文字来组织状态这样一个功能。

    我不知道结果会怎么样。对于社交产品,因为它是群体互动来导致结果的,所以很难预料社交功能交给用户群体后的反应。但是,这样的尝试是应该的。因为,个人的状态表达的需求没有被满足。哪怕是简单的一句“我今天很郁闷”,你不会发朋友圈,也不会跟朋友专门去说,那么,总需要一个地方可以说的。

    歌曲

    还有一个新的尝试是关于听歌的,在座有一位听众跟我聊过怎样看见一首歌,歌不是用来听的,是用来看的。自从有了网络、移动互联网以后,我感觉是很多人听歌变得少了,只有在开车的时候才会听歌,因为在任何其他时候,你会宁愿去看视频了。微信其实是一个包含信息种类特别多的一个东西,但我一直不太满意的一点是在微信里面听歌的体验不太好,比如说我其实特别不理解为什么所有播放器都是一个电唱机在那里转,因为电唱机在我读中学的时候,我家里有一个,我还自己去买唱片,但是我想应该大部分用户不会经历过那个时代,那为什么他们要看不认识的物品,一个唱盘在那里转。

    我们在听歌的时候应该看见什么?很多人说我们在听歌的时候不应该看见什么,而是应该听就好了,但我希望听歌的时候能够看到一点东西,因为听歌的时候有一点想象力,我们之所以希望在开车的时候听,是因为你的眼睛能看到很多的东西,让你的想象比平时更活跃了。如果这些东西,听同一首歌的人往往有很多人,举个例子,你可以想象你在这里听这首歌,另外一个人在另外的场景,还有很多类似的人,如果把他们听歌的眼前画面都连起来的话,总有一些人的画面跟你是非常类似的,他能够打动你的,所以从这个点上出发,我们就把听歌的体验做了一个视觉化的展现。

    但这个难度其实特别大,因为技术还没有到那一步,我们的眼球都有一个摄像头实时传到云端,未来迟早会到那一步。所以目前只能通过别的产品方式才能做到这一步,就是说有一些热心的用户可能会愿意说,我能够把某一首歌变成一个制作得很精美的,类似MV这样一个东西,可以分享给更多的人看到。

    浮窗

    我其实一直很不喜欢浮窗。因为它就像狗皮膏药。这也是PC时代大部分网页浏览的体验都不好的一个原因。

    为了解决一篇文章要很久才看完,而中途要不断处理微信消息的需要,我们有了浮窗功能。但它并不完美。

    很多时候,一篇文章,一个长视频,是要分很多次才看完的,如果每次都要先拖到浮窗,也是很繁琐的。

    现在,微信提供了一个尚未看完的内容的列表,方便可以随时找回这些内容继续看完。尤其是对于长视频,更加需要随时可以切走,然后又能快速找到。直播也一样需要。

    输入法

    还有一个可以提一下的新的研发中的产品,是团队正在研发的输入法。

    我们会经常收到投诉,说刚刚在微信里聊到什么,就在其他app里看到这个东西的广告,是不是微信在出卖我的聊天记录给广告主。其实并不会。我们从来不会去分析用户的聊天记录,即便因此损失了很多广告收入。

    所以当我们的技术团队,就是机器语义理解的团队,说我们自己做输入法可能会做的更好的时候,我当然很赞成。因为至少,在安全性方面,我们可以做的足够好。

    我们的目标不是一下子获取多少用户。因为输入法是文字表达的入口,并且输入法必然越来越智能,可能出现新的输入形态,所以还是值得投入去做的。

    团队

    很多人说视频号迭代速度特别快。事实上在微信的头两年,我们都是这个速度,后来有时快有时慢。其实我认为做产品就是应该快的。

    我经常说的一句话是,如果一个问题,三天没有想出答案的话,那么三个月也想不出来,因此要么三天内找到解决方法,要么放弃,去寻找新的路径,而不是耗在那里。

    孙子兵法说到,行军打仗应该要“其徐如林,其疾如风”。做产品也是这样,要么没有想清楚,那不如什么都不做。如果要做,就要非常快速的迭代。

    视频号团队到目前为止也就一两百人,其中还包括了三个算法团队,前后台开发,产品运营等。这很微信风格。互联网产品是关于创造力的,而不是拼人数。如果一个一百人的团队做不出来一个产品,给一千人也照样做不出来,甚至做的更差,因为一千人的内耗太大了。

    关于产品

    微信十年,如果非要用两个词来描述微信,我想,一个是连接,一个是简单。

    连接是很美的。因为世界的运行就是靠万事万物的连接而进行的。对产品来说,做连接,意味着做服务的底层设施,因为基于连接可以演变出来的结果是最丰富的。

    很多的社交产品可能也做连接,但它止步于人,微信的连接范畴更大,公众号、小程序目标都是连接,连接人和内容、人和服务,包括微信支付也可以认为是一种货币的连接,视频号的目标也是连接。重心不是在做内容,而是在做底层的连接,这很重要。这也是为什么我们会提“去中心化“,因为连接和中心化是有些排斥的。

    再说简单。

    我用简单来作为美观,实用,合理,优雅的代名词。

    简单是很美的。从一个物理公式到一个日常用品,往往是简单的是更好的。实现同样一个目标,有一千种方法,但只有最简单的方法是最美的。正是因为有一千种方法存在,所以要真正做到简单是很难的。

    以前在饭否,看到很多产品越做越复杂,我吐槽说,“一个产品,要加多少功能,才能成为一个垃圾产品啊!” 不是说加功能会让产品不好,而是加了不必要的功能,或者加功能的方式不对。

    十年来,微信加了很多功能。我很庆幸的是,现在的微信,还几乎和十年前的微信一样简单。虽然比十年前多了非常多功能,但这些功能,都已经是用的最简单的办法了,所以增加的复杂度会小。

    简单才会好用。特别是一个产品有十亿人在用的时候。

    有时候也会想,很多用户其实并不一定很在意产品是否简单。粗制滥造的产品,也可能照样会有很多人用的。但是我们还是会追求简单,因为总有部分人,会认同这种简单背后的美感。

    微信虽然是这么大用户量的产品了,并且经历了10年之久了,但我还是希望,它能一直保持自己的风格,一直像一个小而美的产品一样,有自己的灵魂,有自己的审美,有自己的创意,有自己的观念。而不仅仅是数字的奴隶。这样的话,我和团队,才会为我们的工作而感到骄傲,并且觉得有意义,这是我对微信十年在今天的最后一个总结。

    我今天的分享就到这里。

    谢谢现场的朋友们,谢谢观看直播的每一个人,希望我没有浪费你的时间。再见。

    展开全文
  • 淘宝技术这年(淘宝技术大学校长解密淘宝年) 子柳 著 ISBN 978-7-121-20191-2 2013年5月出版 定价:45.00元 252页 16开 编辑推荐 √有熠熠生辉的技术变迁  √有饱含智慧的产品演进 √有叱咤风云...

    淘宝技术这十年(淘宝技术大学校长解密淘宝十年

    子柳 著
    
    ISBN 978-7-121-20191-2
    2013年5月出版
    定价:45.00元
    252页
    16开
    

    编辑推荐

    √有熠熠生辉的技术变迁  

    √有饱含智慧的产品演进

    √有叱咤风云的牛人生涯

     √有令人捧腹的圈内趣事

    无论你是程序员、架构师、产品经理还是运维人员,甚至只要你身处IT圈,这本书都有无穷无尽的 看点,让你大呼过瘾之余,深受启发,进而陷入沉思,不由开始细数自己所在公司的技术发展历程……

    内容提要

    任何网站的发展都不是一蹴而就的。它在发展过程中会遇到各种各样的问题和业务带来的压力。正是这些问题和压力推动着技术的进步和发展,而技术的发展反过来又会促进业务的更大提升。如今淘宝网的流量排名已是全球前15名、国内前3名,其系统服务器也从一台发展到万台以上。

    本书从工程师的角度讲述淘宝这个超大规模互联网系统的成长历程,及其所有主动和被动的技术变革的前因后果。书中有幕后故事、产品经验、架构演进、技术启蒙,也有大牛成长、业内八卦、失败案例、励志故事。全书文风流畅,有技术人员特有的幽默感;内容积极正面,有现场感,全部是作者亲身经历。

    目录

    第0章 引言:光棍节的狂欢 / 1

    淘宝网不就是一个网站吗?是的,但淘宝网不是一个简单的网站,它的规模排在全球前十几名,顶尖的网站需要顶尖的技术作为支撑。在用户享受淘宝的乐趣的背后,有哪些神秘的技术在支撑它呢?

    第1章 个人网站 / 13

    创建一个小小的网站需要什么技术?在群敌环伺的状况下怎么走出网站的第一步?淘宝网独特的文化和价值观又是怎么形成的?本章试图给你一个解读。

    LAMP架构的网站 / 14

    武侠和倒立文化的起源 / 20

    第2章 个人网站的升级 / 23

    小网站都想变大,变大总会遇到成长的烦恼,淘宝网的青春期有哪些烦心事?淘宝网的工程师用什么思路来解决遇到的问题?在解决问题之余,他们又用了哪些创新的手段来超越竞争对手?

    数据库从mySQL到Oracle / 25

    支付手段的创新——支付宝 / 28

    交流方式的创新——淘宝旺旺 / 29

    第3章 企业级Java网站 / 33

    给一个网站更换开发语言,这种事情想想都恐怖,淘宝网在2004年就从PHP语言转换成了Java语言,这是怎么做到的?一个企业级的Java系统应该采用什么样的架构?归纳网站遇到的问题,主要是对性能、容量和成本的控制,这有哪些通用的解决方案?在技术实力得到提升之后,淘宝网的哪些业务有了突飞猛进的发展?哪些业务又会遇到技术的障碍?

    脱胎换骨的升级——更换开发语言 / 34

    坚若磐石——围绕性能、容量和成本的进化 / 41

    第4章 创造技术 / 33

    用钱能解决的问题都不是问题,我们花钱可以购买更好的机器和更好的服务。但当你变成业内最强之后,你的问题就会独特到没有人碰到过,这就意味着你必须自己动手解决问题。幸运的是,淘宝网的发展很快,不幸的是,淘宝网遇到了前所未有的问题。于是,淘宝网被迫开始走向了技术创新的道路。而技术的创新和业务的创新到底又是谁推动了谁?

    淘宝文件系统——TFS / 53

    淘宝KV缓存系统——Tair / 64

    第5章 分布式电子商务操作系统 / 77

    在飞速发展的背后,隐患已经埋下。在技术架构的制约下,团队协作越来越艰难,代码越来越臃肿,开发的效率越来越低,新业务的需求越来越多,老业务的压力眼看就要超过系统的容量了。这时候,架构该做怎样的调整?又一次的脱胎换骨,欲火重生。重生后,在分布式的电子商务操作系统下,我们才敢举办一次又一次的“双十一”活动。

    服务化 / 78

    中间件 / 88

    高性能服务框架HSF / 91

    消息中间件Notify / 95

    分布式数据访问层TDDL / 99

    Session框架 / 107

    开放平台 / 111

    第6章 我在淘宝这八年 / 129

    作为淘宝技术的亲历者,我不经意间见证了一段伟大的历史,这段历史,从高层看波澜壮阔,从底层看妙趣横生。我不是高层,这里记录的是发生在底层的一些事。

    第7章 牛P列传 / 167

    前面讲述了技术和业务是怎么互相促进、共生发展的。与此类似,企业和个人也是这样一个关系:一个水平很高的人,找不到合适的平台,就难以发挥自己的价值;一个蓬勃发展的企业,找不到合适的人才,其前景也会堪忧。幸运的是,在淘宝网蓬勃发展的过程中,出现了一大批业内顶尖的高手,他们推动了淘宝的发展,淘宝也让他们实现了个人的价值。接下来让我们一起看看那些人、那些事。

    正明——集团核心系统高级研究员 / 168

    正祥——淘宝高级研究员,OceanBase项目负责人 / 180

    毕玄——集团核心系统资深技术专家 / 191

    放翁——淘宝开放平台项目负责人 / 198

    吴翰清——阿里云集团信息安全中心高级安全专家 / 210

    云铮——数据平台与产品部资深技术专家 / 218

    小马——淘宝UED前端通用平台高级技术专家 / 225

    淘宝传奇工程师多隆的程序世界 / 236

    精彩节摘

    第0章

    引言:光棍节的狂欢

    淘宝网不就是一个网站吗?是的,但淘宝网不是一个简单的网站,它的规模排在全球前十几名,顶尖的网站需要顶尖的技术作为支撑。在用户享受淘宝的乐趣的背后,有哪些神秘的技术在支撑它呢?

    “时间到,开抢!”坐在电脑前早已等待多时的小美一看时间已到2011年11月11日零时,便迫不及待地投身于淘宝商城一年一度的大型网购促销活动——“淘宝双11购物狂欢节”。小美打开早已收藏好的宝贝——某品牌的雪地靴,飞快的点击购买、付款,一回头发现3000双靴子已被抢购一空。

    小美跳起来,大叫一声“欧耶!”

    小美不知道,就在11日零点过后的这一分钟里,全国有342万人和她一起涌入淘宝商城。当然,她更不知道,此时此刻,在淘宝杭州的一间办公室里,灯火通明,这里是“战时指挥部”,淘宝技术部的一群工程师正紧盯着网站的流量和交易数据。白板上是他们刚刚下的赌注,赌谁能最准确地猜中流量峰值和全天的交易总额。他们的手边放着充足的食物和各类提神的饮料。

    一阵急促的电话铃声响起,是前线部门询问数据的,工程师大声报着:“第1分钟,进入淘宝商城的会员有342万人”。过了一会儿,工程师主动拿起电话:“交易额超过1亿元人民币了,现在是第8分钟。”接下来,“第21分钟,刚突破2亿元”,“第32分钟,3亿元了”,“第1个小时,4.39亿元”。这些数据随后出现在微博上,引起了一片惊呼。

    “完蛋了!”突然有人大喝一声,所有的眼睛都紧张地盯着他,只见他挠挠头,嘿嘿地笑道“我赌得少了,20亿元轻松就能过了,我再加5亿元。”他跑到白板边上把自己的赌注擦去,写上25,接下来有人写上28,有人写上30,有人到微博上开下盘口,同事们纷纷转载下注。接下来的这24个小时,战时指挥部的工程师们都不能休息,他们盯着网站的各种监控指标,适时调整机器,增减功能。顶住第一波高峰之后,这些人开始忙里偷闲地给自己买东西,大家互相交流着哪家买的移动硬盘靠谱,哪家衣服适合自己的女朋友,不时有人哀嚎宝贝被人抢了、信用卡额度不够了。同时,旁边白板上的赌注越下越大。

    11月11日,这个棍子最多的日子被网民自我调侃地变成了一个节日——“光棍节”,而淘宝网又用疯狂的折扣促销给它赋予了另外一个意义——“购物狂欢节”。2011年11月11日这一天,淘宝商城与淘宝网交易额之和突破52亿元人民币,这个数字是“购物天堂”香港一天零售总额8.5亿元的6倍。

    网民感受到的是疯抢的喜悦,而网站的技术人员感受到的却是“压力山大”。就如同你家办酒席,宴请左邻右舍,这个办起来容易,倘若宴请十里八乡所有的人,吃饭的人固然开心,但却不是一般人家能够办得起来的。能办得起来如此盛宴者,需要强大的财力和物力、组织能力、技术实力(例如做这么多菜,你的炒锅一定要是“分布式的”、“可复制的”、“可扩展的”,洗菜和切菜要有“工作流引擎”,跑堂的要计算一下最优路径,甚至连厨房的下水道都要重新设计)。

    淘宝能够举办如此盛宴,网站的技术实力可见一斑。至2011年年底,淘宝网拥有全国最大的Hadoop分布式计算集群之一(2000多个节点,CPU:24000 core,Memory:48000GB,Disk:24000块),日新增数据50TB,有40PB海量数据存储,分布在全国各地80多个节点的CDN网络,支撑的流量超过800Gbps。淘宝的搜索引擎能够对数十亿的商品数据进行实时搜索,另外,还拥有自主研发的文件存储系统和缓存系统,以及Java中间件和消息中间件系统,这一切组成了一个庞大的电子商务操作系统。从商业数据上看,Amazon的财报显示2011年完成了大约 480亿美元的交易额,eBay的2011年财报显示全年完成了大约600亿美元的交易额(不包括其独立的汽车交易平台)。无论从交易额、商品数量还是从同比增速等指标上看,淘宝网均远超于此,是目前全球最大的电子商务平台。(由于淘宝是非上市公司,未公布2011年的业绩,以上内容来自淘宝网技术副总裁@_行癫的微博)。

    以上这些技术数据可能已经让一些人产生了不适的感觉,为了让更多的人读懂这本书,我们用下面这段文字描述一下小美访问淘宝网的时候,从技术的角度来看,网站上发生了什么样的事情。

    参考资料来自《你刚才在淘宝上买了一件东西》(来自阿里员工卡特)

    作者简介

    子柳:本名赵超,2004年加入淘宝网,取花名子柳。历任开发工程师、项目经理、产品经理、测试经 理,2009年随着淘宝系统的大规模重构和人才的迅速扩张,创办了“淘宝技术大学”,培养内外部工 程师众多,人称“校长”。2011年将培训中的内容写成文章发表,遂一发不可收拾,总结了淘宝十年 的技术之路,乃成本书。

    媒体评论

    相信这本书将掀起IT技术型企业的寻根热潮,因为阅读本书让我们深深体会到“以史为鉴”在互联网时 代的当下意义。创业公司的无暇顾及,大牌公司的千头万绪,都抵不过一次美妙的现身说法。这本书让整个IT界一起陷入思考:我们的十年曾如何走过,我们的十年将如何走过,或是我们的十年正在走过?

     

    子柳是个能人,在淘宝各个阶段各个角落都曾留下各种姿态的身影。也正因为是历次技术沿革及产品诞生的亲历者,他的记录与解读,可以让读者置身于那段波澜壮阔的淘宝技术岁月;更能切中要害,精准 捕捉到最值得总结和回味的技术关键点及创新闪光点。子柳更是个趣人,知交满淘宝,内幕岂能少?一桩桩尘封往事,在这样一位称职“耳目”的妙笔下再现昔日荣光,局外人方有幸品历当年甘苦,共享经 验启迪。

    前言

    这是一本好玩的书,从前面两章看,主要是讲故事;从后面两章看,主要是讲人物;从中间几章看,主要是讲技术。我在写作的过程中,把部分章节的内容放到了我的博客上,有人看了说很励志,有人看了说对技术有帮助,有人看了说对产品有帮助,有人看了说对创业有帮助,有人看了说其中的内容特别逗,现在我也不知道这是人文读物还是技术书了。

    其实技术书很容易写成催眠的读物,对于这本书,我一开始就没有当作技术书来写,最早是我写给自己看的。在2011年年底的时候,我突然意识到在淘宝度过了七年的时光,七年说长不长,说短不短,回忆起来有些往事历历在目,有些却已开始模糊。为了给自己留点回忆,我就开始记录自己这几年的故事,七年之间发生了很多有趣的事情,越写越多,写着写着,我就希望能够挖掘更多的内容了。当时我还担任着“淘宝技术大学”的校长,这给我的写作提供了得天独厚的优势,我可以听不同的人讲淘宝技术所有的事情。于是我就开始凭记忆去写淘宝在过去几年的技术进展,再去找当事人求证内容的细节。然后又由于有些当事人实在太有料了,我干脆把跟他交谈的内容也整理出来,当作《牛P列传》来呈现给读者(淘宝的技术人员以P级来定义,牛P就是很高级别的专家)。至此,本书包含了三种行文格式的内容:一个是笔者自己经历的美好时光,一个是淘宝技术的发展历程,一个是那些牛人的牛事。希望能够通过这三个维度,让读者对淘宝的技术有一个概括的了解,进而通过淘宝对互联网的技术有一个概览。

    书名取为《淘宝技术这十年》,口气有点大了,但我很难用一个更确切的名字来概括本书的内容,淘宝在这十年里的技术是很难用一本书来写完的,对于笔者不太熟悉的领域(例如运维、云计算、大数据),没敢着墨太多,书中主要围绕网站的业务和系统架构之间的关系展开论述。我希望能够抛砖引玉,未来有更多的人来写《淘宝运维这十年》《淘宝数据这十年》……

    写完本书之后,再回过头来读,我意识到自己经历了一场伟大的变革,这个时代把电子商务推到了一个浪潮之巅,我是这个浪潮中的一滴水珠,我无意描述这场伟大的浪潮,只希望通过一滴水珠映射出浪潮底下的故事。这不是淘宝官方的史书,我不具备这样的高度和视野,这只是一个小人物的所见所想。

    这本书写得很轻松,我大概花了3个月时间就写完了,这主要得益于其中的事情都是笔者亲身经历的。同时,这种写作状态也直接导致了本书的行文风格天马行空,一边讲业务,一边讲技术,时不时地还做一些不太高明的点评。从2011年年底开始写,到2012年年初,书中的主要内容都有了,接下来就是求证各种细节的过程,这比初稿要艰难很多,我访谈了书中提到的几乎所有人,有时候还要请他们帮忙补充一些内容,由于人员众多,这里不一一列出,在此一并表示感谢——亲,这是我们共同的作品。

    这里特别要提出感谢的是我的师父岳旭强,他比我更早加入淘宝,行文的时间线是根据他给我讲的故事来写的。他现在是蘑菇街的CTO,属于自己创业。他离开淘宝也是触动我写本书的原因之一,铁打的营盘,流水的兵,虽然淘宝的人员流失率总体较低,但是每离开一个人就失去了一段故事,如果我现在不写,未来也许很难呈现出过往的这一切了。老天选择了我做技术,选择了我能写点文字,选择了我经历淘宝的发展,选择了我做淘宝技术大学的校长,似乎也选择了我要把这些故事交代给读者。

    其次要感谢对本书贡献最大的一个人,书里的故事是我在“淘宝技术大学”给学员上课时讲的,但每个故事的第一个听众都不是技术人员,也不是淘宝员工,是我家里的CEO,她经常被我当作学生,听我讲一个多小时的课,然后给我指出各种不足。同时,为了让我安心写作,她也赦免了我很多家务活,谢谢亲。

    最后要感谢本书的编辑张春雨先生,他花费了很大精力帮我修改书稿,在他的帮助下,本书从网文变得像一本书了。另外,虽然本书经历了笔者和编辑的多次修改,但这如同开发软件一样,上线之后发现bug的概率还是很大的,如有错漏之处,敬请读者不吝赐教。

    子柳@杭州

    2013年4月1日

    展开全文
  • 工作年,分享看过的优质 Java 书籍

    万次阅读 多人点赞 2019-12-13 10:38:32
    这期间我读了不少 Java 方面的书籍,纸质版的说有三来本吧,更何况还有不少的电子书。万事都有好坏,书也一样。有的是精神粮食,有的纯粹是浪费时间。这里就分享一些我精挑细选后的优质书籍,希望能帮大家走点...
  • 淘宝年产品事

    千次阅读 2013-10-12 17:01:58
    淘宝年产品事(《人人都是产品经理》案例版《淘宝技术这年》姊妹篇) 苏杰 编著 ISBN 978-7-121-21572-8 2013年10月出版 定价:55.00元 252页 16开 编辑推荐  这本书适合所有工作、生活中与淘宝产生...
  • 程序员的层楼

    万次阅读 热门讨论 2009-02-08 22:44:00
     转载:http://softwareblogs-zho.intel.com/2009/02/04/1071/ 程序员的层楼(1~3层)作者: 周伟明 自西方文艺复兴以来,中国在自然科学方面落后西方很,软件领域也不例外。当然现在中国的许多程序员们对此...
  • 九月月百度人搜,阿里巴巴,腾讯华为小米搜狗笔试面试八题引言 自发表上一篇文章至今(事实上,上篇文章更新了近3个月之久),blog已经停了3个月,而在那之前,自开博以来的21个月每月都不曾断过。...
  • 虚拟内存可以在你电脑内存条不够用时,把一部分的硬盘空间作为内存来使用,从而让电脑可以执行更的应用程序,如果C盘已经捉襟见肘,不妨把它放到空间更大的其他盘去。 如何操作呢?桌面右击【此电脑】,选择【属性...
  • 程序员的“三而已”

    千次阅读 多人点赞 2020-08-05 09:53:27
    虽然看得,但我大致已经了解到,《三而已》这部剧是干嘛的,它描写了都市女性在 30 岁人生节点上面临家庭、事业、爱情上的种种波折,以及她们的态度和选择。并且成功引起了我老婆的共鸣——深深的。 女人是人,...
  • 《淘宝技术这年》读书总结

    千次阅读 2013-11-14 23:34:03
    本文摘要最近认真看了《淘宝技术这年》这本书,感觉甚好。内容丰富,故事、技术、人物,应有尽有。今天,终于把这本书的读书总结写完了,有兴趣的可以看看。内容摘要序:作者对书的介绍,写作原由和感受。第0章:...
  • [干货分享] 反省我年开发犯过的错

    万次阅读 多人点赞 2016-11-11 01:39:22
    原文链接:... ...反省我年开发犯过的错反省我年开发犯过的错 专注于一个方向平台 框架语言 别为了薪水去做管理 不需要那么忙 敲敲敲不要停 主动加入社群 别从网上投简
  • 年总结(终):新的年,新的起点

    万次阅读 热门讨论 2009-09-26 22:58:00
    对我过去感兴趣的朋友们,请看... 年并不是一个短暂的时光,但发生的真正有价值的事情却并不, 我尽量保证每一篇都有一定的思考和意义在其中。 坚持写下来,需要不少的精力、毅力和耐心。还好,有很朋友的支持,
  • 十多岁的你,迷茫又着急

    千次阅读 多人点赞 2018-01-31 10:50:43
    20岁的你,迷茫又着急。 你想要房子想要汽车, 你想要旅行想要享受生活。 你那么年轻却窥觑整个世界, 你那么浮躁却想要看透生活。 你不断催促自己赶快成长,却沉不下心来安静的读一篇文章; 你一次次吹响...
  • spring boot 致力于简洁,让开发者写更的配置,程序能够更快的运行和启动。它是下一代javaweb框架,并且它是spring cloud(微服务)的基础。 二、搭建第一个sping boot 程序 可以在start.spring.io上建项目,...
  • session 存储在内存中,在用户量较时访问效率较高,但如果一个服务器保存了几几百万个 session 就十分难顶了。同时由于同一用户的次请求需要访问到同一服务器,不能简单做集群,需要通过一些策略(session ...
  • 年职场

    千次阅读 2008-06-04 10:19:00
    2008年的3月的某一天,看到公司论坛上有人在庆祝自己工作满一年,突然意识到原来自己的职场生涯也到了第个年头。还记得工作五年的时候写了一篇《我的东软五年》,结果传遍了“大江南北”,后来据说都转发到了东软...
  • CMM/CMMI的20年和敏捷

    千次阅读 2011-09-22 07:07:08
    近来在InfoQ上陆续翻译了纪念回顾敏捷年的文章,在CMM/CMMI/Agile都有兴趣的我不由得想到从1991年CMM1.0发布之时算起,今年正好也是CMM/CMMI的20年。 对比看下两者的历史,也许会有些意思。 SEI1986年在美国国防...
  • 本文是我最近读书笔记的一篇文章,主要是阅读《淘宝技术这年》的第一部分,主要包括淘宝网的技术流程和基础介绍,希望文章对大家有所帮助,同时记录自己最近学习的内容。我似乎是2007年初中看《赢在中国》的时候...
  • 读《淘宝技术这年》有感

    千次阅读 2019-02-18 22:52:11
    前言 不知不觉间,在微信读书看书已经有好几个小时了,也许是因为都是零碎时间看...刚好,最近读完的《淘宝技术这年》在读的过程中做了一些摘抄,对有一些内容也是深有感触。 论成功学的好坏 从前往后看,首先比...
  • 太讲究方法和技巧会被其占用很的时间和精力,而对学习的内容本身投入较的时间和精力,因此反而会影响学习的效果。如有一个参加高等教育自学考试的青年,他订了多种讲自学和考试的刊物,认真学习和研究,讲起...
  • 从事嵌入式研发行业年,认为学习就是要不断的吸纳知识,在研发过程中,经常会遇到一些问题,这种发现问题并解决问题的过程就是进步。为什么选择学习嵌入式?嵌入式系统无疑是当前最热门最有发展前途的IT应用领域之...
  • 第二八~二九章:最大连续乘积子串、字符串编辑距离前言 时间转瞬即逝,一转眼,又有4个月没来更新blog了,过去4个月都在干啥呢?对的,今2013年元旦和朋友利用业余时间一起搭了个方便朋友们找工作的编程面试...
  • EXCEL内容文件却很大---如何变小

    万次阅读 2015-09-23 17:38:59
    后来全选整个工作表,删除其内容,除了一个工作表外,其它工作表内容都能删除,但文件依然很大,而这个工作表,删除部分单元格是没问题的,按ctrl+END,定位到最后一个“使用过”的单元格时,发现尽然是104857
  • 第三四~三五章:格子取数问题,完美洗牌算法的变形题记 再过一个半月,即到2013年10月11日,本博客便是开通3周年,巧的是,这天刚好也是我的25岁生日。写博近三年,访问量趋近500万,无法确切知道帮助了多少人...
  • 程序员编程艺术第二~五章:中签概率,IP访问次数,回文等问题(初稿)作者:上善若水.qinyu,BigPotato,luuillu,well,July。编程艺术室出品。前言 本文的全部稿件是由我们编程艺术室的部分成员:上善若水....
  • ❤️万字《C语言动漫教程》❤️

    万次阅读 多人点赞 2021-07-14 22:53:11
    《夜深人静写算法》 零、初章   欢迎大家踊跃评论,优秀的评论更能引起大家的共鸣,评论超过20字,或有内涵,或点赞前名,都将获得 《夜深人静写算法》 和 《C语言入门100例》的 5 折优惠券(各一张) ,三天为...
  • 雷军—我年的程序员生涯

    万次阅读 多人点赞 2018-05-05 00:00:00
    内容转自:http://blog.sina.com.cn/s/blog_4b0e23c90100b2qf.html最近,和UCWEB同事讨论,怎么才能把我们的UCWEB做...
  • 时光荏苒,美团岁了,美团技术团队也走过了个春秋。 2010年3月4日美团网上线的时候,整个公司总共来人,在一套三居室的民房里起步。其中技术团队只有5个人,现在有4位还在美团。 今天,美团是中国市值第三的...
  • 看过一些文章,看过一些优秀的IT人,他们有些是从小就有对IT方面有着很大的激情以及天赋,而我,现在二十多岁了,却一直碌碌无为,有时候跟一些从事IT行业的人聊一聊,发现他们说的一些内容自己听的懂得简直太,不...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 321,431
精华内容 128,572
关键字:

十多十少内容