2017小红书校园招聘面试经历

小红书是上海的一家基于b2c的电商,虽然没有阿里巴巴的名气但是也是一家处于快速发展的企业,这个公司对算法比较重视,一上来就要求用递归方法写

一个全排列,幸好还记得一些思路,最后还是被我写出来了,一下是当时写的代码:

#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<sstream>
#include<fstream>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;


vector<vector<int>>get_all_permutation(vector<int>&data, int end){
	vector<vector<int>>re;
	vector<vector<int>>tmp;
	if (end == 0){
		vector<int>temp;
		temp.push_back(data[end]);
		re.push_back(temp);
		return re;
	}
	re = get_all_permutation(data, end - 1);
	for (int i = 0; i<re.size(); i++){
		int count = 0;
		vector<int>::iterator iter;
		int size = re[i].size();
		int index = 0;
		while (count != size + 1){
			iter = re[i].begin();
			for (int k = 0; k < index; k++)iter++;
			re[i].insert(iter, data[end]);
			tmp.push_back(re[i]);
			iter = re[i].begin();
			for (int k = 0; k < index; k++)iter++;
			re[i].erase(iter);
			index++;
			count++;
		}
	}
	return tmp;
}

int main() {
	int num;
	vector<int>data;
	vector<vector<int>>re;
	int count = 1;
	while (count){
		num = 0;
		if (num<1){
			cout << 0 << endl;
			return 0;
		}
		for (int i = 1; i <= num; i++)data.push_back(i);
		re = get_all_permutation(data, num - 1);
		cout << '[';
		for (int i = 0; i<re.size(); i++){
			cout << '[';
			for (int j = 0; j<re[i].size(); j++){
				cout << re[i][j];
				if (j != re[i].size() - 1)cout << ',';
			}
			cout << ']';
			if (i != re.size() - 1)cout << ',';
		}
		cout << ']' << endl;
		count--;
	}
	return 0;
}


//Input: 数字 n 
//Output: 以二维数组的形式,输出[1,2,...,n]的全排列。 
//例如:当n=3时,输出[[1,2,3], [1,3,2], ..., [3,2,1]]

//标准解法:递归。


这种方法比较乱,主要思想是利用插空法,假设我们在a,b,c三个字符的情况下,我们调用函数递归调用返回b,c和c,b那么我们可以将a插入到b,c和c,b的每一位

置,那么对于b,c来说,就会有abc,bac,bca,对于c,b来说,我们就有acb,cab,cba;

但是在正常情况下,我们的输出序列为:

1, 2, 3
1, 3, 2
2, 1, 3
2, 3, 1
3, 1, 2
3, 2, 1

后来又写了另外一种方法:

#include<iostream>
#include<string>
#include<vector>
#include<memory>
#include<fstream>
using namespace std;

vector<vector<int>> get_all_permutation(vector<int>&data,int begin){
	vector<vector<int>>re;
	vector<int>tmp;
	if (begin == data.size()-2){//这个时候还剩两个元素
		tmp.push_back(data[begin]);
		tmp.push_back(data[begin+1]);
		re.push_back(tmp);
		//交换两个数
		tmp[0] = tmp[0] ^ tmp[1];
		tmp[1] = tmp[0] ^ tmp[1];
		tmp[0] = tmp[0] ^ tmp[1];
		re.push_back(tmp);
		return re;
	}
	re = get_all_permutation(data,begin+1);
	for (int i = 0; i < re.size(); i++)re[i].insert(re[i].begin(), data[begin]);
	int num = re.size();
	for (int i = 0; i < num; i++){//将0号下标和从1号下标开始的元素交换
		for (int j = 1; j < re[i].size(); j++){
			tmp = re[i];
			tmp[0] = tmp[0] + tmp[j];
			tmp[j] = tmp[0] - tmp[j];
			tmp[0] = tmp[0] - tmp[j];
			re.push_back(tmp);
		}	
	}
	return re;
}

int main(){
	int num;
	vector<int>data;
	vector<vector<int>>re;
	while (cin>>num){
		if (num == 0)return  0;
		if (num == 1){ cout << num << endl; continue; }
		for (int i = 1; i <= num; i++)data.push_back(i);
		re = get_all_permutation(data,0);
		cout << '[';
		for (int i = 0; i < re.size();i++){
			cout << '[';
			for (int j = 0; j < re[i].size(); j++){
				cout << re[i][j];
				if (j != re[i].size() - 1)cout << ',';
			}
			cout << ']';
		}
		cout << ']' << endl;
		data.clear();
	}
}

再用树的结构来写一遍(这种思想用到dfs和回溯方法):

#include<vector>
#include<memory>
#include<fstream>
#include<stack>
using namespace std;

void get_all_permutation(vector<int>&data,vector<bool>&flag,vector<int>&stk){//begin代表当前的下标
	int size = data.size();
	if (stk.size() == data.size()){
		cout << '[';
		for (int i = 0; i < stk.size(); i++){
			cout << stk[i];
			if (i != stk.size() - 1)cout << ',';
		}
		cout << ']';
		return;
	}
	for (int i = 0; i < size;i++){
		if (flag[i] != true){//可以继续访问
			flag[i] = true;
			stk.push_back(data[i]);
			get_all_permutation(data,flag,stk);
			stk.pop_back();
			flag[i] = false;
		}
	}
}

int main(){
	int num;
	vector<int>data;
	vector<vector<int>>re;
	vector<bool>flag;
	while (cin>>num){
		if (num == 0)return  0;
		if (num == 1){ cout << num << endl; continue; }
		for (int i = 0; i < num; i++)flag.push_back(false);
		for (int i = 1; i <= num; i++)data.push_back(i);
		cout << '[';
		int count = 0;
		vector<int>stack;
		get_all_permutation(data,flag,stack);
		cout << ']' << endl;
		data.clear();
		flag.clear();
	}
}

可以用STL里面的next_permutation函数实现一遍



### 杭州小红书 Java 开发岗面试经验及相关题目 #### 面试准备建议 在准备杭州小红书公司的 Java 开发岗位时,需注意简历的优化以及技术知识点的全面掌握。根据过往的经验,一份优秀的简历应着重展示个人参与的核心项目及其成果[^3]。如果简历未能清晰体现项目的贡献度和技术细节,则可能会影响面试官的第一印象。 #### 技术考察方向 以下是基于行业经验和实际案例总结的小红书 Java 岗位常见技术考点: 1. **线程池与并发编程** 线程池的设计原理是高频问题之一。例如,在实现线程池的过程中如何处理任务队列的选择至关重要。当提到无界队列时,可能会进一步探讨其潜在风险——即可能导致内存溢出的情况[^1]。因此,候选人需要熟悉 JVM 的垃圾回收机制 (GC),尤其是针对对象存活判断的方法,比如引用计法和根可达分析算法。 2. **JVM 调优** 对于 JVM 的深入理解也是必不可少的部分。具体来说,应该能够解释清楚 GC 的工作流程、不同代之间的划分依据,以及如何通过调整参来提升性能表现。此外,还需要知道 JVM 是怎样识别并标记那些不再使用的对象作为可被清理的目标。 3. **项目实战经历** 实际工作中遇到的技术难题同样会被询问到。这不仅考验解决问题的能力,还反映了候选人在面对复杂场景下的思考方式。例如可以描述一次因高并发请求而导致系统崩溃的经历,并阐述最终采取何种措施解决了该问题。 4. **据结构与算法基础** 虽然上述内容更偏向应用层面的知识点,但扎实的据结构与算法功底依然是成功获取 offer 的关键因素。常见的有二叉树遍历操作、动态规划求解背包问题等经典模型的应用实例演示。 ```java // 示例代码:简单的二叉树前序遍历方法 public class TreeNode { int val; TreeNode left, right; public void preOrderTraversal(TreeNode node){ if(node != null){ System.out.print(node.val+" "); preOrderTraversal(node.left); preOrderTraversal(node.right); } } } ``` 5. **分布式架构设计** 随着互联网业务规模不断扩大,单体架构逐渐向微服务转型成为趋势所在。对于应聘者而言,具备一定的分布式系统构建思维尤为重要。像 CAP 定理的理解程度、一致性哈希算法的实际运用等方面都可能是讨论的重点话题。 --- #### 总结 综上所述,参加杭州小红书 Java 开发职位面试之前,除了精心打磨自己的求职材料外,还需加强对多领域专业知识的学习积累。只有做到理论联系实际才能从容应对各种类型的考核环节。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值