完全没有准备的一次面试……意外

两部分:Word2vec + 中位数 (还有聊对科研的想法和自己研究能力的评价?

word2vec

//解释模型
原本是one-hot,存在缺点:稀疏和无法表现语义,词与词之间无法计算距离 //CBOW和skip-gram简要介绍一下是什么
CBOW模型的训练输入是某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量。
Skip-Gram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。 //这两种算法如何选择
CBOW对小型数据比较合适,skip-gram在大型语料中表现更好 //word2vec的损失函数是什么
NCE-loss: NCE的主要思想是,对于每一个样本,除了他自己的label,同时采样出N个其他的label,从而我们只需要计算样本在这N+1个label上的概率,而不用计算样本在所有label上的概率。
峰哥教我是负采样?使用所谓的“负采样”(negative sampling)来改进优化对象,这将造成每一个训练的样本只会更对模型权重的很小一个比例的更新。
//瞎扯了交叉熵
因为上面的问题回答错了嘛……sigh
信息熵 + 相对熵= 交叉熵
K-L散度:就是相对熵,是一种量化两种概率分布P和Q之间差异的方式。
换句话说,KL散度计算的就是数据的原分布与近似分布的概率的对数差的期望值。

如何找出一个整数数组的中位数:

//最简单的思路
排序,quicksort然后找中位数【nlogn】 //quicksort的最差情况
时间复杂度【n^】就是每次选定的数都是最大或者最小 //改进一点的找中位数的做法
partition法 ,利用快排关键字的查找方法
a.随机选取一个关键字key,将序列二分;
b.若关键字的下标大于N/,则继续对序列的左半部分执行partition;
c.若关键字的下标小于N/,则继续对序列的左半部分执行partition;
d.若关键字的下标等于N/,则返回key。
这种算法:partition的时间复杂度为【O(n)】因为是n+n/+n/+n/+…所以是O(n)
取中位数的时间复杂度是【O()】
简单解释就是:每次会丢掉一半 //堆
原理分析:
中位数无非就是将序列分为两个部分,左边的部分都小于中位数,右边的序列都大于中位数。这比较符合堆的特性(看看数据结构在算法中的重要性,选择好的数据结构能够让算法事半功倍)。可以将序列分成两个部分,左边的部分够着大根堆,右边的部分构造小根堆。
具体实现细节:
a.如果堆中元素的个数为偶数时,将新数字插入小根堆中(插入后堆元素的个数为奇数,此时结束插入,返回小根堆堆顶元素);如果堆中的元素个数为奇数时,将新数字插入大根堆中(插入后堆元素的个数为偶数,此时结束插入,返回两堆堆顶元素的均值)。
b.若插入小根堆的元素大于大根堆堆顶的元素,说明新元素位于序列的右半部分,应当插入大根堆。而此时大根堆堆顶元素应当位于左半序列(小顶堆)中,因此需要将大根堆堆顶元素插入小根堆。若插入若插入小顶堆的元素不大于大顶堆堆顶的元素,则直接插入小根堆。
c.同理,向大根堆插入元素时也有如上考虑。
调整堆的时间复杂度为【O(logn)】,取中位数的时间复杂度为【O()】。 参考:https://blog.csdn.net/cpu_12593/article/details/48231213
面试题41

partition函数找中位数的写法(做递归之前要判断):

求第k大数的时候,pivot的不满足条件的那一侧数据不需要再去处理了,平均时间复杂度为O(N+N/2+N/4+...)=O(N)。而快排则需要处理,复杂度为O(nlogn)。

public int findMiddleByPartition(int[] array, int left, int right) {
int i = left, j = right;
int key = array[left];
while(i < j) {
// j向左走,直到找到一个小于key的数
while(i < j && array[j] >= key) j--;
if(i < j) {
array[i] = array[j];
i++;
}
// i向右走,直到找到一个大于key的数
while(i < j && array[i] <= key) i++;
if(i < j) {
array[j] = array[i];
j--;
}
}
array[i] = key;
if(i == array.length / 2) {
return i;
}else if(i < array.length / 2){
return findMiddleByPartition(array, i + 1, right);
}else {
return findMiddleByPartition(array, left, i - 1);
} }

  

堆排序的方法,自己的语言复述:

将数据平均分配到构建的最大堆和最小堆中,为了实现平均分配,可以在数据的总数目是偶数的时候把新数据插入最小堆,否则插入最大堆。

为了保证最大堆中的所有数据都小于最小堆中的数据,当数据的数目是偶数的时候,先把这个新的数据加入最大堆,然后把最大堆中的最大数字拿出来插入最小堆,反之当数据中的数目是奇数的时候,先把这个新的数据加入最小堆,然后把最小堆中的最小值加入最大堆。

template<typename T> class DynamicArray{
public:
  void Insert (T num){
    if ((min.size() + max.size())& == ){    //这是偶数
      if (max.size()> && num <max[]){  
        max.push_back(num);       //加入最大堆
        push_heap(max.begin(). max.end(), less<T>());
        num = max[];          //取max的最大
        pop_heap(max.begin(), max.end(), less<T>());
        max.pop_back();
      }
      min.push_back(num);        //将max的最大放入min
      push_heap(min.begin(),min.end(),greater<T>());
    }
    else{
      //类似上面的部分,只是加入最小堆,把最小堆的最小取出来,放入最大堆
    }
  }
  
  T GetMedian(){      //返回中位数
    int size = min.size() + max.size();
    if (size == )
      throw exception("No numbers are available");
    T median = ;
    if ((size &)==)
      median = min[];
    else
      median = (min[]+max[])/;
    return median;
  } private:
  vector<T> min;
  vector<T> max;  //用vector实现堆!!!
}

  

附加题:如果数据非常多,要确定准确的中位数,应该怎么做?

这里,采用基于二进制位比较 和 快速排序算法中的“分割思想”来寻找中位数。具体如下:

假设10亿个数字保存在一个大文件中,依次读一部分文件到内存(不超过内存的限制:1GB),将每个数字用二进制表示,比较二进制的最高位(第32位),如果数字的最高位为0,则将这个数字写入 file_0文件中;如果最高位为 1,则将该数字写入file_1文件中。【这里的最高位类似于快速排序中的枢轴元素】

从而将10亿个数字分成了两个文件(几乎是二分的),假设 file_0文件中有 6亿 个数字,file_1文件中有 4亿 个数字。那么中位数就在 file_0 文件中,并且是 file_0 文件中所有数字排序之后的第 1亿 个数字。

【为什么呢?因为10亿个数字的中位数是10亿个数排序之后的第5亿个数。现在file_0有6亿个数,file_1有4亿个数,file_0中的数都比file_1中的数要大(最高位为符号位,file_1中的数都是负数,file_0中的数都是正数,也即这里一共只有4亿个负数,排序之后的第5亿个数一定是正数,那么排序之后的第5亿个数一定位于file_0中)】。除去4亿个负数,中位数就是6亿个正数从小到大排序之后 的第 1 亿个数。

现在,我们只需要处理 file_0 文件了(不需要再考虑file_1文件)。对于 file_0 文件,同样采取上面的措施处理:将file_0文件依次读一部分到内存(不超内存限制:1GB),将每个数字用二进制表示,比较二进制的 次高位(第31位),如果数字的次高位为0,写入file_0_0文件中;如果次高位为1,写入file_0_1文件 中。

现假设 file_0_0文件中有3亿个数字,file_0_1中也有3亿个数字,则中位数就是:file_0_0文件中的数字从小到大排序之后的第1亿个数字。

抛弃file_0_1文件,继续对 file_0_0文件 根据 次次高位(第30位) 划分,假设此次划分的两个文件为:file_0_0_0中有0.5亿个数字,file_0_0_1中有2.5亿个数字,那么中位数就是 file_0_0_1文件中的所有数字排序之后的 第 0.5亿 个数。

......

按照上述思路,直到划分的文件可直接加载进内存时(比如划分的文件中只有5KW个数字了),就可以直接对数字进行快速排序,找出中位数了。当然,你也使用“快排的分割算法”来找出中位数(比使用快速排序要快)

总结:上面的海量数据寻找中位数,其实就是利用了“分割”思想,每次将 问题空间 大约分解成原问题空间的一半左右。(划分成两个文件,直接丢弃其中一个文件),故总的复杂度可视为O(logN)

【interview——Ali】project interview_18 summer的更多相关文章

  1. 【intellij idea】Project Structure 讲解

    项目的左侧面板 项目设置->Project Project Settings -> Modules Sources面板 Paths面板 dependencies面板 Project Set ...

  2. 21. 【intellij idea】Project Structure 讲解

    转自:.https://www.cnblogs.com/zadomn0920/p/6196962.html 项目的左侧面板 项目设置->Project Project Settings -> ...

  3. 【核心】project(idea文件)、module(iml文件)到SSM集成、热部署、Tomcat启动、MAVEN依赖冲突

    http://wiki.jikexueyuan.com/project/intellij-idea-tutorial/project-composition-introduce.html 在 Inte ...

  4. 【Visual Studio】The project appears to be under source control, but the associated source control plug-in is not installed on this computer

    [问题描述]用 Visual Studio 2013打开一个项目时,出现下面错误: [问题原因]参考 http://codeverge.com/asp.net.web-forms/the-projec ...

  5. 【57.97%】【codeforces Round #380A】Interview with Oleg

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  6. 【已解决】Android Studio下,gradle project sync failed 错误

    原文:[已解决]Android Studio下,gradle project sync failed 错误 Android studio下突然报错 gradle project sync failed ...

  7. 震撼,java面试题整合(良心制作)11万多字拿去。持续更新【可以收藏】

    一.javaSE面试题整合 Java部分 JDK中哪些类是不能继承的?[信雅达面试题] [参考答案] 不能继承的是类是那些用final关键字修饰的类.一般比较基本的类型或防止扩展类无意间破坏原来方法的 ...

  8. 【.NET MF】.NET Micro Framework USB移植

    1.开发环境 windows 7  32位 MDK 4.54 .Net Micro Framework Porting Kit 4.2(RTM QFE2) .Net Micro Framework   ...

  9. 冰冻三尺非一日之寒--Django框架【进阶篇】

    第十九章  Django进阶 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去 ...

随机推荐

  1. pytorch错误:Missing key(s) in state_dict、Unexpected key(s) in state_dict解决

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 在模型训练时加上: model = nn.DataParallel(model)cudnn.bench ...

  2. Spring MVC 使用介绍(十六)数据验证 (三)分组、自定义、跨参数、其他

    一.概述 除了依赖注入.方法参数,Bean Validation 1.1定义的功能还包括: 1.分组验证 2.自定义验证规则 3.类级别验证 4.跨参数验证 5.组合多个验证注解 6.其他 二.分组验 ...

  3. MySQL——修改用户密码 | 移除权限

    修改用户密码 '; 移除权限 REVOKE Delete, Drop ON *.* FROM `root`@`localhost`; 权限列表

  4. Auto Layout Masonry

    1. Auto layout 1.1 NSLayoutConstraint 1.1.1 约束类 ios6.0可用 为了更好的适配各个尺寸 1.1.2 constraintWithItem:attrib ...

  5. CBV源码分析

    1 在views中写一个类,继承View,里面写get方法,post方法 2 在路由中配置: url(r'^test/', views.Test.as_view()),实际上第二个参数位置,放的还是一 ...

  6. P1962 斐波那契数列-题解(矩阵乘法扩展)

    https://www.luogu.org/problemnew/show/P1962(题目传送) n的范围很大,显然用普通O(N)的递推求F(n)铁定超时了.这里介绍一种用矩阵快速幂实现的解法: 首 ...

  7. iis7设置ftp

    目前是所有网站一个域下.ftp登录后可看到所有网站,目前想ftp一个网站,查看了下服务器,貌似只有serv-u这么个东西,还不能再创建第二个域.不得其解.百度发现两篇文章正好: http://blog ...

  8. linux date -s

    修改linux的时间可以使用date指令 修改日期: 时间设定成2009年5月10日的命令如下: #date -s 05/10/2009 修改时间: 将系统时间设定成上午10点18分0秒的命令如下.  ...

  9. Security+高分考过经验分享812分

    Security +也是无意中从谷安的宣传单知道的,本来就是想从事安全的行业,而且Security +含金量高,是国际认可的认证就想着去考一考试试. 大概从2018.12开始正式准备的,前面时间都是停 ...

  10. python2 配置环境变量

     复习 '''重点:1.进制转换:二进制 与 十六进制2.内存分布:栈区 与 堆区 # 124810101001110111 => 2a77abf1 => 1010101111110001 ...