This is my thrid blog web site.

0%

Java 内部类

  • 常规内部类
  • 局部内部类
    • 定义在方法内部
  • 匿名内部类
  • 静态嵌套类
    • 只能访问静态成员

Java 类

1
2
3
4
5
public class JA{
public JA () {

}
}

常规内部类

JavaScript 类

1
2
3
4
5
6
7
8
9
class A {
constructor() {

}
}

function A () {

}

面试 Android

记了面经,但是忘了是哪一家公司了

  • 自我介绍
  • 项目经历
    • 小米
      • miui资源替换工具
        • flutter
          • dart文件上传下载,调用原生原生包
    • 商汤
  • Android
    • handler
    • handler机制
    • 事件分发
    • 自定义view
    • rxjava
  • java
    • 继承
    • 多态
      • 重载重写
      • 原理
    • 抽象
      • interface
      • 抽象类
    • 线程池
  • 算法
    • 下面
    • 有一个inter啥 没听清 不会
  • 内存泄漏
  • Android学习
  • 写过什么
    • 浏览器
    • 桌面助手

1、给出一个有序数组和一个数,求数组中连续元素的和等于所给数的子数组
如:[1,2,2,3,5,6,7,8,9],再给一个数5,求数组中连续元素的和等于5的子数组:[1,2,2]、[2,3]和 [5]

2、给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

  • 2020/03/25 10:00 - 11:00 二面
    • suanfa
      • let
      • 数组去重
      • 数字倒序
      • 长连接短链接
    • photoshop
  • 一面
    • http3
      • udp 头变了
    • css
      • flex有什么不好实现的
    • js
      • 新语法
    • 项目
    • 自我介绍
    • vue
  • 03/31 11:00 三面
    • 项目

头条-ailab后端

刚好需要前后端都做过的人。面试问的前端部分多

一面

记到别的地方,找不到了

二面 03/27 下午12:30

头条二面

  • 自我介绍
  • react
  • 后端
    • koa 怎么样
  • 跨域
  • 部署
  • 浏览器同源策略
  • cookie
  • let var
  • ldap
  • 时间戳四舍五入
  • 手写sleep
  • css移动端适配
    • dp
1
2
3
4
5
6
7
8
9
10
11
12
let sleep = (time) => {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve()
},time)
})
}
async () => {
a()
await sleep(1000)
b()
}

美团-前端

一面

上来面试官先自我介绍了,但是我没听清名字,然后说已经看过我的简历了,让我说一下兴趣.
面试官一边问一边对我做出肯定,面得特别开心。

  • 自我介绍
  • js基础
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let arr = [{i:1},{i:2},{i,3}]
    let newArr = []

    newArr.push(arr[0])
    arr.forEach(i => {
    i.i = i.i+1
    })

    console.log(newArr[0])
    围绕这些做了变体
  • vue基础

data: () => {
arr: [0,1,2]
}

arr[0] = 1

会不会更新,为甚么
主要还是问vue的数据绑定,但是关于数组的数据绑定没了解过,但是可以知道他肯定不会变
[1]
需要变的话可能得对数组赋值,或者强制更新

  • electron
    • 主进程和渲染进程
    • 同步异步
      • 同步
        • evenet。returnValue
      • 异步
        • event。sender。send

主要讲了一下我当时写主进程渲染进程交互的时候遇到的比较恶心的情况,解决方法是封装出一个mvp模式

  • 进程与线程

讲了一下,概念,再讲了一下具体

  • 进程调度算法

讲了先入先出和按权重来。这部分都忘光光了

  • 同步锁

讲了java的同步锁和wait notify

  • 网络
    • tcp与udp的区别
  • 提了一下java内存回收和JavaScript内存回收机制类似
  • 其他不记得了
  • 算法
    • 判断循环依赖
1
2
3
4
a -> b,c
b -> c,d
c ->
d -> a
  • 问我有什么问题
    • 我问了为什么会问我electron 是不是美团有做这方面的东西
      • 答 有electron和智能硬件的交互,要调c 。 感觉牛逼,可以看一下

二面

  • 自我介绍等
  • 问了一个问题
    • 用面向对象实现一个流程图
      • 不清楚如何去描述]
      • 这里的流程图指的是程序设计中的流程图,而不是订单流程之类的东西
  • 设计模式
    • 只说了用过的的,没在课上学过
  • 操作系统
    • 问了大概
  • 计网
    • 问了大概,基本没问
  • 聊天为主
  • 算法学了什么
    • 问了快排,快排的时间复杂度
  • 数据结构学了什么
    • 链表,顺序表,树,图,
    • 堆没学
    • 图的相关计算不太记得
  • vue中的面向对象

[1] (https://blog.csdn.net/kirinlau/article/details/78027312)

面试-腾讯-基础开发

一面

面试体验巨好,超级好,牛逼

  • js题
    • setTimeout
  • 算法题
    • sort 二分找最小
    • 合并有序节点
    • 查找第三大的节点
  • java 多线程
    • 生产者消费者
  • js模块化
  • electron
    • 进程通信
  • 开源项目
    • 看了我的简历写的开源项目,问了一下
      • 怎么编译kotlin到js
  • Android
    • Activity生命周期 ,应该是看到我简历有写,就简单问了一下
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163
      164
      165
      166
      167
      168
      169
      170
      171
      172
      173
      174
      175
      176
      177
      178
      179
      180
      181
      182
      183
      184
      185
      186
      187
      188
      189
      190
      191
      192
      193
      194
      195
      196
      197
      198
      199
      200
      201
      202
      203
      204
      205
      206
      207
      208
      209
      210
      211
      212
      213
      214
      215
      216
      217
      218
      219
      220
      221
      222
      223
      224
      225
      226
      227
      228
      229
      230
      231
      232
      233
      234
      235
      236
      237
      238
      239
      240
      241
      242
      243
      244
      245
      246
      247
      248
      249
      250
      251
      252
      253
      254
      255
      256
      257
      258
      259
      260
      261
      262
      263
      264
      265
      266
      267
      268
      269
      270
      271
      272
      273
      274
      275
      276
      277
      278
      279
      280
      281
      282
      283
      284
      285
      286
      287
      288
      289
      290
      291
      292
      293
      294
      295
      296
      297
      298
      299
      300
      301
      302
      303
      304
      305
      306
      307
      308
      309
      310
      311
      312
      313
      314
      315
      316
      317
      318
      319
      320
      321
      322
      323
      324
      325
      326
      327
      328
      329
      330
      331
      332
      333
      334
      335
      336
      337
      338
      339
      340
      341
      342
      343
      344
      345
      346
      347
      348
      349
      350
      351
      352
      353
      354
      355
      356
      357
      358
      359
      360
      361
      362
      363
      364
      365
      366
      367
      368
      // 45分钟

      题目1(js基础): 阅读下面代码,写出结果
      let data = { "a": 1, "b": 101 }
      function read(readUseTime) {
      return new Promise(resolve => {
      setTimeout(() => {
      resolve({...data})
      }, readUseTime)
      })
      }

      function write(value, writeUseTime) {
      console.info('write ',value)
      return new Promise(resolve => {
      setTimeout(() => {
      data = value
      resolve()
      }, writeUseTime)
      })
      }

      async function readAndWrite(key, value, readUseTime = 0, writeUseTime = 0) {
      let d = await read(readUseTime)
      d[key] = value
      await write(d, writeUseTime)
      }

      ;(() => {
      setTimeout(readAndWrite, 0, 'a', 2)
      setTimeout(readAndWrite, 0, 'b', 102)
      setTimeout(() => {
      // 输出结果
      console.log(data)
      }, 1000)
      })()
      { "a": 1, "b": 102 }

      进一步问:必需输出的是 { "a": 2, "b": 102 },怎么修改function readAndWrite

      var isdo = null
      async function readAndWrite(key, value, readUseTime = 0, writeUseTime = 0) {
      if (isdo != null)
      await isdo;

      isdo = new Promise(async (resolve,reject)=>{
      let d = await read(readUseTime)
      d[key] = value
      resolve(d)
      }).then((res)=> {
      return new Promise(async (resolve, reject)=>{

      await write(res, writeUseTime)
      isdo = false
      resolve()
      })
      })

      }

      var h = setTimeout(() => { h = null; }, 1000)
      if (h == undefined) { }
      isdo = new Promise


      ;(() => {
      setTimeout(readAndWrite, 0, 'a', 2)

      setTimeout(readAndWrite, 0, 'b', 102)
      setTimeout(() => {
      // 输出结果
      console.log(data)
      }, 1000)
      })()
      题目2(算法):合并两个从小到大链表的链表,使用的算法越快越好。
      比如:L1={1,3,5}, L2={2,4}, L1.merge(L2)后,L1={1,2,3,4,5}, L2={}
      class LinkNode {
      private int val;
      private LinkNode next;
      public void merge(LinkNode node) {
      // TODO 请完成实现部分
      }
      }


      function LinkNode () {

      this.val = 0;
      this.next = null
      this.merge = function (node) {
      let head = new LinkNode()
      let res = head
      let l1 = node
      let l2 = this

      //if

      while(l1 != null || l2 != null) {
      let nex
      if (l1.val < l2.val) {
      res.insert(l1)
      l1 = l1.next
      res = res.next
      } else if (l1.val > l2.val) {
      res.insert(l2)
      l2 = l2.next
      res = res.next
      }
      }

      if (l1 != null) {
      res = l1
      } else {
      res = l2
      }
      this.next = head.next
      this.val = head.val
      }

      this.insert = function (node) {
      let nex = this.next
      // let nodex = node.next
      this.next = node
      node.next = nex
      // node = nodex
      }
      }

      //bu yong new node
      function LinkNode () {

      this.val = 0;
      this.next = null
      this.merge = function (node) {

      let res = null
      let l1 = node
      let l2 = this



      let head = l1.val <= l2.val? l1:l2
      res = head
      //if
      if(head.val == l1.val) l1 = l1.next
      else l2 = l2.next

      while(l1 != null || l2 != null) {
      if (l1.val < l2.val) {
      l1.insert(l2)
      l1 = l1.next

      } else if (l1.val > l2.val) {
      l2 = l2.next
      }
      }

      if (l1 != null) {
      res = l1
      } else {
      res = l2
      }

      }

      this.insert = function (node) {
      let nex = this.next
      // let nodex = node.next
      this.next = node
      node.next = nex
      // node = nodex
      }
      }



      题目3(算法):给定一个递增循环整数数组,从里面找出最小的元素,使用的算法越快越好。特别地,最小的元素可能出现在数组中间。比如:50, 52, 63, 90, 3, 8, 15, 44。
      class Problem2 {
      int findmin(int[] array) {
      // TODO 请完成实现部分

      }
      }


      var findMin = function (arr) {
      return arr.sort((b,a) => b-a)[0]
      }

      var findMin = function (arr ) {
      let l =0
      let m = parseInt(arr.length/2)
      let r = arr.length-1
      if (arr.length==2) return Math.min(arr[0],arr[1])
      if (arr.length==1) return arr[0]
      console.info(arr)
      if (arr[l] <= arr[m]){
      return Math.min(arr[l],findMin(arr.slice(m+1)))
      }else {
      return Math.min(arr[m],findMin(arr.slice(0,m)))
      }
      }


      题目4(算法):在二叉排序树上面找出第3大的节点。注意:不能把二叉树全量存储到另外的存储空间,比如存储到数组中,然后取出数组的第三个元素。
      class TreeNode {
      int value;
      TreeNode left, right;
      };

      class Problem3 {
      TreeNode find(TreeNode root) {
      // TODO 请完成实现部分

      }
      }

      var res = []
      var find = function (root) {
      findMax(root)
      return res[0]
      }
      var add = function add(arr, v) {
      if (arr.length >2) {
      arr[0] = arr[1]
      arr[1] = arr[2]
      arr[2] = v
      }
      else {
      arr.push(v)
      }
      return arr
      }
      var finMax = function (root) {
      if (root.left != null) {
      res = add(res,root.left.value)
      }

      res = add(res,root.value)
      if (root.right != null) {
      return findMax(root.right)
      }
      }



      题目5(java多线程):阅读下面代码,在2线程环境下,设计一个方案,判断无限数据流(Stream)每个正整数是否素数,越快越好
      interface Stream {
      long get(); // 获取下一个需判断的整数
      void put(boolean result); // 返回整数是否素数的结果
      static boolean isPrimeNumber(long num) { // 判断一个整数是否素数
      if (num < 2) return false;
      for (long i = 2, s = (long) Math.sqrt(num); i <= s; i++) {
      if (num % i == 0) return false;
      }
      return true;
      }
      static Stream getInstance() {
      try {
      return (Stream) Class.forName("StreamImpl").newInstance(); // 运行环境保证不会异常
      } catch (Exception e) {
      return null;
      }
      }
      }
      比如:Stream={1,2,3,4,...}, Result={false,true,true,false,...},注意输出顺序。
      public class Problem5 {
      private Stream stream = Stream.getInstance();
      private long t1;
      public void thread1() throws InterruptedException {
      assert Thread.currentThread().getName() == "thread1";
      // TODO 请完成实现部分
      long t = stream.get()
      boolean b = Stream.isPrimeNumber(t)

      stream.notify()
      t1
      stream.put(

      )
      stream.wait();
      }
      public void thread2() throws InterruptedException {
      assert Thread.currentThread().getName() == "thread2";

      long t = stream.get()
      boolean b = Stream.isPrimeNumber(t)
      stream.wait();
      stream.put(
      Stream.isPrimeNumber(stream.get())
      )
      stream.notify()
      }
      // TODO 请完成实现部分

      public static void main(String[] args) {
      Problem5 p5 = new Problem5()
      new Thread(new Runnable() {
      @Override
      void run() {

      try {
      p5.thread1();
      } catch (Exception e) {

      }
      },"thread1").start();

      new Thread(new Runnable() {
      @Override
      void run() {
      try {
      p5.thread2();
      } catch (Exception e) {

      }
      },"thread2").start();

      }
      }


      js基础:js模块化有哪些
      引用js模块
      require
      require('xxx.js')
      import A from 'hjk.js'
      import AC from 'jjj.vue'

      一个得到的是引用
      一个得到的是一个对象

      import 大部分时候通过 babel 实现

      node不支持直接使用import

      为了支持es6 有一个新的js运行环境 deno ?



      electron基础:Main进程,Renderer进程如何通信


      ipcMain

      ipcMain.on('xxx-event',(event,arg) =>{
      //do some
      event.sender.send('')
      }

      ipcRender.send

      -- remote



      build.gradle
      task complieJs (type: Exec, group: 'custom') {
      workingDir '.'
      commandLine 'kotlinc-js', '-output', 'node-publish/lib/kfmd.js' , "build/source", '-module-kind', 'commonjs'
      }
      // A problem occurred starting process 'command 'kotlinc-js''

      var core = kfmd.Core()
      var html = core.setContainorClass('demo').trans(a)


      Android

二面 2020/03/30 8:30

  • 项目
  • 概率题
  • 老鼠吃药二进制
  • 打乱扑克牌

美团 Android 一面

感觉问得有点奇怪

  • 冒泡
    • 排序算法时间复杂度
    • 优化
  • 哈夫曼 哈夫曼编码
    • 觉得我生成的结果反了
  • 瀑布模型
  • onclick
  • 自定义view属性
  • 点击渐变颜色
  • 聊了一下快应用 rn 容器
  • 看了下我的github的code
  • 主要聊天了

冒泡可以优化,忘了还能这样优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

let sort = function (arr) {
let change = true
let t = 0
while(change) {
change = false
for (let x = 0; x < arr.length-1; x++) {
if (arr[x] > arr[x+1]) {
t = arr[x]
arr[x] = arr[x+1]
arr[x+1] = t
change = true
}
}
}

return arr
}

// 优化过
let sort2 = function (arr) {
let change = true
let t = 0
let l = arr.length-1
while(change && l >0) {
change = false
for (let x = 0; x < l ; x++) {
if (arr[x] > arr[x+1]) {
t = arr[x]
arr[x] = arr[x+1]
arr[x+1] = t
change = true
}
}
l--
}

return arr
}

About Android 5 Service

启动和生命周期

  • 启动方式
    • startService
      • 无限期运行
      • 生命周期
        • onCreate
        • onStartCommand
        • onDestory
    • bindService

      • onCreate
      • onBind
      • onUnbind
      • onDestory
  • 手动调用
    • startService
      • 单次
        • onCreate
        • onStartCommand
      • 多次
        • onCreate
        • onStartCommand
        • onStartCommand
    • stopService
      • onDestory
    • bindService
      • onCreate
      • onBind
    • unbindService
      • onUnbind
      • onDestory
  • 解绑绑定Service服务
    • unbindService() —> onUnbind(ture) —> bindService() —> onRebind()

Service 与 Thread

无相关,只是有点像。
Service运行与主线程,只要进程不消失则继续运行
Thread运行在其他线程,

IntentService

在IntentService的Oncreate中,开启一个新的线程,并绑定一个handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

@Override
public void onCreate() {
super.onCreate()

HandlerThread thread = new Handler("IntenteService["+ mName+"]")
thread.start()

mServiceLooper = thread.getLooper()

mServiceHandler = new ServiceHandler(mServiceLooper);
}

public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent,startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;

msg.obj = intent;

mServiceHandler.sendMessage(msg)
}

ServiceHandler的源码

1
2
3
4
5
6
7
8
9
10
11
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper)
}

@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent) msg.obj);
stopSelf(msg.arg1);
}
}

Service 与Activity通信

  • onbind返回Ibinder对象
  • unbindService和bindService的时候参入ServiceConnection对象

Remote Service IPC

  • IPC
  • AIDL

参考
1
2
3

About Android 4 Handler

  • Handler
  • Message
  • MessageQueue
  • Looper
  • HandlerThread

Handler

handler 的使用方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//1 post postDelay
Handler.post / postDelay (new Runnable() {
@Override
void run() {
//todo
}
})

//2 sendMessage

创建handler
实现handlerMessage接口

handler.sendMessage(msg)

Activity finish时handler未执行完会引发Activity内存泄漏?

优化

  • 通过静态内部类+弱引用方式实现handler
  • 等等

HandlerThread

HandlerThread继承Thread.

run方法内进行Looper的初始化相关操作

Looper

  • Looper.prepare
    • 从TheadLocal中取得Looper对象,执行多次会抛出异常
1
2
3
4
5
6
7
8
9
10
11
12
13

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
//...
public static void prepare() {
prepare(true);
}

private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only on lopper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
  • Looper.loop()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void loop() {
final Looper me = myLooper();
//..
final MessageQueue queue = me.mQueue;
//..
for(;;) {
Message msg = queue.next();
//..
msg.target.dispatchMessage(msg)
//ms.target 是一个handler对象
//Handler 在 enqueueMessage() 内为msg添加target
}
//..
msg.recycleUnchecked()
}

About Android 3 持久化存储

  • Android 持久化存储
    • Shared Preference
    • Internal Storage
    • External Storage
    • SQLite Database
    • Network Connection

Shared Preferences

  • 特点
  • 原理

SharedPreferences的特点

适合单线程,小批量数据存储和访问

SharedPreferences原理

通过维护一个xml文件存储

多进程使用

不推荐使用

Internal Storage & External Storage

sdcard数据读写需要注意权限

数据库

  • sqlite
  • greenDAO
  • realm

常问:
数据库的操作是线程安全的吗?
太久没操作了

网络

序列化支持

  • 序列化
    • Parceable
      • 高效 Android 特有 复杂
    • Serial
      • io操作多 性能影响大

参考
1
数据库的设计:深入理解 Realm 的多线程处理机制