1、数据仓库的结构?
数据仓库是一个用于存储、管理和分析大规模数据的集中式数据存储系统。它的结构通常包括以下主要组件和层次。
2、python-逆序对取模
逆序对取模通常需要使用归并排序算法。逆序对在一个数组中,如果一个数比其后面的数大,则称这两个数构成一个逆序对。
def merge_sort(arr, mod):
if len(arr) > 1:
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
left_half, left_inv_count = merge_sort(left_half, mod)
right_half, right_inv_count = merge_sort(right_half, mod)
merged_arr, split_inv_count = merge(left_half, right_half, mod)
inv_count = left_inv_count + right_inv_count + split_inv_count
return merged_arr, inv_count
else:
return arr, 0
def merge(left, right, mod):
merged_arr = []
inv_count = 0
i = j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
merged_arr.append(left[i])
i += 1
else:
merged_arr.append(right[j])
j += 1
inv_count += len(left) - i
merged_arr.extend(left[i:])
merged_arr.extend(right[j:])
return merged_arr, inv_count
def count_inverse_pairs(arr, mod):
_, inv_count = merge_sort(arr, mod)
return inv_count % mod
# 示例用法
arr = [2, 4, 1, 3, 5]
mod = 1000000007
result = count_inverse_pairs(arr, mod)
print("逆序对数取模结果:", result)
3、Python-合并两个已排序的数组
方法:使用双指针的方法,遍历两个输入数组,逐个比较元素,将较小的元素添加到新数组中。
def merge_sorted_arrays(arr1, arr2):
merged_arr = []
i = j = 0
while i < len(arr1) and j < len(arr2):
if arr1[i] < arr2[j]:
merged_arr.append(arr1[i])
i += 1
else:
merged_arr.append(arr2[j])
j += 1
# 将剩余的元素添加到新数组中
while i < len(arr1):
merged_arr.append(arr1[i])
i += 1
while j < len(arr2):
merged_arr.append(arr2[j])
j += 1
return merged_arr
# 示例用法
arr1 = [1, 3, 5, 7]
arr2 = [2, 4, 6, 8]
result = merge_sorted_arrays(arr1, arr2)
print("合并后的已排序数组:", result)
4、Spark和Hadoop是大数据处理领域的两个重要框架,它们有一些异同点。
相同点:
不同点:
5、Java-二分查找
public int search(int[] nums, int left, int right, int target) {
while (left <= right){
int mid = left + (right - left) / 2;
if (nums[mid] == target){
return mid;
}else if (nums[mid]< target){
return search(num, mid + 1, right, target);
}else{
return search(num, left, mid - 1, target);
}
}
return -1;
}
6、Java-双指针
递增数组,判断数组中是否存在两个数之和为target,思路为双指针,一个begin,一个end,每次移动一个指针
public int[] twoSum(int[] numbers, int target) {
int p1 = 0;
int p2 = numbers.length - 1;
while (p1 < p2){
int sum = numbers[p1] + numbers[p2];
if (sum == target){
return new int[]{p1 + 1, p2 + 1};
} else if (sum < target){
p1++;
} else {
p2--;
}
}
//无解
return new int[]{-1, -1};
}
7、Java-最长递增子序列LIS(动态规划)
给一个整数数组nums,找到其中最长严格递增子序列的长度。最优时间复杂度为O(nlogn)
public int lengthOfLIS(int[] nums) {
int dp[] = new int[nums.length];
dp[0] = 1;
int maxSeqLen = 1;
for (int i=1; i nums[j]){
dp[i] = Math.max(dp[i], dp[j]+1);
}
}
maxSeqLen = Math.max(maxSeqLen, dp[i]);
}
return maxSeqLen;
}
8、逆序链表两数求和
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode pre = new ListNode(0);
ListNode cur = pre;
int carry = 0;
while(l1 != null || l2 != null) {
int x = l1 == null ? 0 : l1.val;
int y = l2 == null ? 0 : l2.val;
int sum = x + y + carry;
carry = sum / 10;
sum = sum % 10;
cur.next = new ListNode(sum);
cur = cur.next;
if(l1 != null)
l1 = l1.next;
if(l2 != null)
l2 = l2.next;
}
if(carry == 1) {
cur.next = new ListNode(carry);
}
return pre.next;
}
}
9、Mysql的三范式
第一范式(1NF):数据表中的每一列都包含不可再分的原子数据,也就是每个单元格中只能存储一个值。所有的数据必须是原子的,不能包含集合、数组、嵌套表格等非原子数据。
第二范式(2NF):数据表必须符合第一范式(1NF)。所有非主键列(非关键字列)都必须完全依赖于候选键(主键)。 这意味着没有部分依赖,即表中的每一列都应该与主键有关系,而不是只与主键的一部分有关。
第三范式(3NF):数据表必须符合第二范式(2NF)。所有非主键列都不应该传递依赖于主键。换句话说,非主键列之间不应该存在传递依赖关系。如果一个非主键列依赖于另一个非主键列,而后者又依赖于主键,那么就存在传递依赖,这需要通过分解表来消除。非主键都和主键直接相关,不存在间接相关。
10、Mysql的InnoDB和MyIsam的区别
11、MySQL的隔离级别