iOS开发经常用到的技术知识点

1.刷新单个tableviewcell

NSIndexPath * indexPat=[NSIndexPath indexPathForRow:indexPlay inSection:0];

NSArray * indexArray=[NSArray arrayWithObject:indexPat];

[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];

2.   判断该方法是否执行??

BOOL isss=  [cell.queuePlayer respondsToSelector:@selector(play)];

instancesRespondToSelector是指类的实例们是否能响应某一个方法(类操作),respondsToSelector是指类是否能响应某一方法(对象)
3.代码块的使用
int (^oneFrom)(int) = ^(int anInt) {

return anInt -1;

};

NSLog(@”%d”,oneFrom(10));

4.  改变buuton的高亮

UIImageView * iv = [[UIImageView alloc] initWithFrame:CGRectMake(250, 5, 50, 34)];

iv.userInteractionEnabled = YES;

UIButton * navBtn = [UIButton buttonWithType:UIButtonTypeCustom];

navBtn.frame = CGRectMake(0, 0, 50, 34);

[navBtn setImage:[UIImage imageNamed:@”rong_Tian”] forState:UIControlStateNormal];

[navBtn setHighlighted:YES];

[navBtn addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside];

[navBtn setShowsTouchWhenHighlighted:YES];

[iv addSubview:navBtn];

[self.navigationController.navigationBar addSubview:iv];

5. 默认为cell*行

 

NSIndexPath *first=[NSIndexPath indexPathForRow:0 inSection:0];

[self.tableView selectRowAtIndexPath:first animated:YES scrollPosition:UITableViewScrollPositionBottom];

6.一个项目中  ARC和非ARC 的混合使用

 

点击项目–》TARGETS-》Build Phases  -》Compile  Sources   中选择要改的.m   双击   在标签中写:

1.如果是ARC项目,要加入非ARC的代码文件  fobjc-arc

2.如果是非ARC,要加入ARC的代码   -fno-objc-arc       Enter就OK

 

//    NSURL * url=[NSURL URLWithString:str];

//

//      NSURLRequest *requestt = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];

//     NSData *received = [NSURLConnection sendSynchronousRequest:requestt returningResponse:nil error:nil];

//    NSString *strr = [[NSString alloc]initWithData:received encoding:NSUTF8StringEncoding];

//    NSLog(@”这是  成功返回的信息     %@”,strr);

7.距离感应器

UIDeviceOrientation orientation3=  [[UIDevice currentDevice] orientation];

 

NSLog(@”获取当前状态   %d”,orientation3);

[[UIDevice currentDevice] setProximityMonitoringEnabled:YES];

[[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(sensorStateChange:)

name:@”UIDeviceProximityStateDidChangeNotification”

 

object:nil];

-(void)sensorStateChange:(NSNotificationCenter *)notification;

{

if ([[UIDevice currentDevice] proximityState] == YES) {

 

NSLog(@”Device is close to user”);

//在此写接近时,要做的操作逻辑代码

}else{

NSLog(@”Device is not close to user”);

}

}

8.获得cookie

 

NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];

for (NSHTTPCookie *cookie in [cookieJar cookies]) {

NSLog(@”cookie=====     %@”, cookie);

}

9.从相册中只获得视频文件

 

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] == YES)

{

UIImagePickerController *videoLibraryController = [[[UIImagePickerController alloc] init] autorelease];

videoLibraryController.delegate = self;

videoLibraryController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

videoLibraryController.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];

[videoLibraryController setAllowsEditing:YES];

[self.navigationController presentViewController:videoLibraryController animated:YES completion:^{

 

}];

}

else

{

[self AlertlogError:@”暂时你还没有视频”];

}

10. 读取全局的Delegate:
KiloNetAppDelegate *appdelegate = (KiloNetAppDelegate *)[[UIApplication sharedApplication] delegate];

11.键盘透明

textField.keyboardAppearance = UIKeyboardAppearanceAlert;
12.URL错误:
Error Domain=ASIHTTPRequestErrorDomain Code=5 “Unable to create request (bad url?)” UserInfo=0x69ba0f0 {NSLocalizedDescription=Unable to create request (bad url?)}

解决办法:

NSString*url =@”http://oerp.xixingsoft.com:8083/oadata/MobileConfig.nsf/GetStandList?openagent&ViewNumber=新闻中心”;

url=[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

 

NSStringEncodingenc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);//gbk code–>utf8 code

NSData*data = [url dataUsingEncoding:NSUTF8StringEncoding];//[request responseData];

NSString*utf8str = [[[NSStringalloc] initWithData:data encoding:enc] autorelease];

13.请求中加cookie、 heard

当你需要添加更多的请求信息时,如,添加个请求Header:
[request addRequestHeader:@”name” value:@”Jory lee”];

14 Plist文件的保存 修改    除非在decument是可读可写的(在工程中  可读不可写)

//获取路径对象

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

//获取完整路径

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:@”test.plist”];

NSLog(@”plist  地质   %@”,plistPath);

NSMutableDictionary *dictplist = [[NSMutableDictionary alloc ] init];

[dictplist setObject:self.strWeb_id forKey:@”web_id”];

[dictplist writeToFile:plistPath atomically:YES];

15.获取文件夹的大小

-(long long) fileSizeAtPath:(NSString*) filePath{

NSFileManager* manager = [NSFileManager defaultManager];

if ([manager fileExistsAtPath:filePath]){

return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];

}

return 0;

}

16.改变tablevlewcell点击的颜色

 

cell.selectedBackgroundView = [[[UIView alloc] initWithFrame:cell.frame] autorelease];

cell.selectedBackgroundView.backgroundColor = [UIColor colorWithRed:54/255.0f green:110/255.0f blue:100/255.0f alpha:1.0f];

cell.textLabel.highlightedTextColor = [UIColor xxxcolor];  [cell.textLabel setTextColor:color

 

点击后,过段时间cell自动取消选中
[self performSelector:@selector(deselect) withObject:nil afterDelay:0.5f];

– (void)deselect

{

[self.tableVieww deselectRowAtIndexPath:[self.tableVieww indexPathForSelectedRow] animated:YES];

}

17.改变UITableViewStyleGrouped背景颜色

 

self.tableVieww.backgroundColor =[UIColor colorWithPatternImage:[UIImage imageNamed:@”更多背景图.png”]];

self.tableVieww.backgroundView =nil;

18.视图反转

//水平
queuePlayer.transform = CGAffineTransformScale(queuePlayer.transform, 1.0, -1.0);
//垂直    queuePlayer.transform = CGAffineTransformScale(queuePlayer.transform, -1.0, 1.0);
19.改变icon的阴影圆圈,取消图标上的高光

1.进入plist文件    2.在Supported interface orientations 添加  Icon already includes gloss effects  设置为YES              也就是用自己的icon,不用系统的了

20.动态UIlable后添加图片

self.userNameLabel=[[[UILabel alloc]initWithFrame:CGRectMake(60, 7, 220, 20)]autorelease];

self.userNameLabel.textColor= [UIColor blackColor];

self.userNameLabel.text=self.strNamee;

self.userNameLabel.backgroundColor=[UIColor clearColor];

self.userNameLabel.numberOfLines=0;

UIFont *font = [UIFont fontWithName:@”Helvetica-Bold” size:17.0f];

[self.userNameLabel setFont:font];

[self.contentView addSubview:self.userNameLabel];

CGSize size = [self.strNamee sizeWithFont:font constrainedToSize:CGSizeMake(277, 20.0f)];

NSLog(@”kuang %f  “,size.width);

CGRect rect=self.userNameLabel.frame;

rect.size=size;

NSLog(@”321    %f    %f”,rect.size.width,rect.size.height);

[self.userNameLabel setFrame:rect];

//判断男女

UIImageView * imaSex=[[UIImageView alloc]initWithFrame:CGRectMake(self.userNameLabel.frame.size.width+65, 10, 12, 13)];

21.向自定义的cell中传值,*好用 方法在tableview中来调用 如果有参数  直接来传
22.精确时间差
//时间差

– (NSString *)intervalSinceNow: (NSString *) theDate

{

NSDateFormatter *date=[[NSDateFormatter alloc] init];

[date setDateFormat:@”yyyy-MM-dd HH:mm:ss”];

NSDate *d=[date dateFromString:theDate];

NSTimeInterval late=[d timeIntervalSince1970]*1;

NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];

NSTimeInterval now=[dat timeIntervalSince1970]*1;

NSString *timeString=@””;

NSTimeInterval cha=now-late;

if (cha/3600<1) {

timeString = [NSString stringWithFormat:@”%f”, cha/60];

timeString = [timeString substringToIndex:timeString.length-7];

timeString=[NSString stringWithFormat:@”%@分钟前”, timeString];

 

}

if (cha/3600>1&&cha/86400<1) {

timeString = [NSString stringWithFormat:@”%f”, cha/3600];

timeString = [timeString substringToIndex:timeString.length-7];

timeString=[NSString stringWithFormat:@”%@小时前”, timeString];

}

if (cha/86400>1)

{

timeString = [NSString stringWithFormat:@”%f”, cha/86400];

timeString = [timeString substringToIndex:timeString.length-7];

timeString=[NSString stringWithFormat:@”%@天前”, timeString];

 

}

[date release];

return timeString;

}

22.按钮在cell上单击第几行

在cell.contentView上:

//获得row

NSInteger row = [[self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]] row];

//获得section

NSInteger row = [[self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]] section];

//获得indexPath

NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];

直接添加到cell上:
//获得row
NSInteger row = [[self.tableView indexPathForCell:(UITableViewCell *)[sender superview]] row];
//获得section
NSInteger section = [[self.tableView indexPathForCell:(UITableViewCell *)[sender superview]] section];
//获得indexPath
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[sender superview]];
23:判断Home键在哪个方法要执行对应的方法
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rongTianOrientation:) name:@”UIDeviceOrientationDidChangeNotification” object:nil];

 

– (void) deviceOrientationDidChangeAction:(NSNotification *)note

{

NSInteger currentOrientation = [[note object] orientation];

switch (currentOrientation)  {

case0: {   //未知方向

break;

}

case1: {   //home键向下

break;

}

case2: {   //home键向上

break;

}

case3: {  //home键向左

break;

}

case4: {  //home键向右

break;

}

default:

break;

}

}

24.模拟器不能运行的错误

dyld: Library not loaded: @rpath/SenTestingKit.framework/Versi*****/A/SenTestingKit
Referenced from: /Users/⋯⋯/Application Support/iPhone Simulator/5.0/Applicati*****/F179924C-0EB7-4CCA-88D6-3BA1F68F122D/ILUTU.app/ILUTU
Reason: image not found

 

把SentestingKit。 frameWork 有原来的required改为Optional  就ok

25.还原状态栏

显示原来的状态栏

(1)

[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:YES];

[[UIApplication sharedApplication].keyWindow setFrame:CGRectMake(0, 20, 320, [UIScreen mainScreen].applicationFrame.size.height)];

 

//重新设定标题栏显示的位置

[self.navigationController.navigationBar setFrame:CGRectMake(0, 0, 320, 44)];

(2)

在别的页面[[UIApplication sharedApplication].keyWindow setFrame:CGRectMake(0, 0, 320, [UIScreenmainScreen].applicationFrame.size.height)];

26.获得相册视频的总时间
– (int)getVideopTime:(NSURL * )videourl

{
NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumbernumberWithBool:NO]

forKey:AVURLAssetPreferPreciseDurationAndTimingKey];

AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:videourl options:opts]; //初始化视频媒体文件

int minute = 0, second = 0;

second = urlAsset.duration.value / urlAsset.duration.timescale; // 获取视频总时长,单位秒

NSLog(@”movie duration : %d”, second);

if (second >= 60) {
int index = second / 60;

minute = index;

second = second – index*60;

}

return second;

}

27.视频播放器 循环播放 大小……

(1) MPMoviePlayerController

MPMoviePlayerController *player;

NSURL *url =[NSURL URLWithString:fileName];

player = [[MPMoviePlayerController alloc] init];

player.view.frame = CGRectMake(10, 30, 300    , 225);

player.contentURL = url;

player.repeatMode = MPMovieRepeatModeOne;

player.controlStyle = MPMovieControlStyleEmbedded;

 

player.scalingMode = MPMovieScalingModeAspectFill;   //充满屏幕

[self.view addSubview:player.view];

[player play];

(2).avplayer

 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:)                                                       name:AVPlayerItemDidPlayToEndTimeNotification

object:plaitem];

}

}];

#pragma mark – Notification Callbacks

– (void)playerItemDidReachEnd:(NSNotification *)notification {
NSLog(@”是跳转*侦吗?  “);

[self.queuePlayer seekToTime:kCMTimeZero];

[self.queuePlayer play];

}

28.sina微博错误返回值格式

http://open.weibo.com/wiki/Error_code

29.ios 获得文件夹的大小

 

//计算文件夹下文件的总大小

-(long)fileSizeForDir:(NSString*)path

{

NSFileManager *fileManager = [[NSFileManager alloc] init];

long size = 0;

NSArray* array = [fileManager contentsOfDirectoryAtPath:path error:nil];

for(int i = 0; i<[array count]; i++)

{

NSString *fullPath = [path stringByAppendingPathComponent:[array objectAtIndex:i]];

 

BOOL isDir;

if ( !([fileManager fileExistsAtPath:fullPath isDirectory:&isDir] && isDir) )

{

NSDictionary *fileAttributeDic=[fileManager attributesOfItemAtPath:fullPath error:nil];

size+= fileAttributeDic.fileSize;

}        else        {

[self fileSizeForDir:fullPath];

}

}

[fileManager release];    return size;    }

30.    谓词过滤

//搜索用谓词过滤数组

NSArray * arrMy=@[@”张2荣三a”,@”李四b”,@”王五a”,@”李流j”,@”荣天321″,@”iOS基地”,@”iOS7″];

NSString  * strg=@”荣”;

NSPredicate * fiecate=[NSPredicate predicateWithFormat:@”SELF CONTAINS %@”,strg];

NSArray * arr3=[arrMy filteredArrayUsingPredicate:fiecate];

NSLog(@”这是我过滤的数组对吗?%@”,arr3);

31.多线程的多种创建

 

//    NSThread * th=[[NSThread alloc]initWithTarget:self selector:@selector(thAction) object:nil];

//    [th start];

 

//[NSThread detachNewThreadSelector:@selector(thAction) toTarget:self withObject:nil];

 

// [self performSelectorInBackground:@selector(thAction) withObject:self];

 

//    NSOperationQueue * operationQueue=[[NSOperationQueue alloc]init];

//    [operationQueue addOperationWithBlock:^{

//        for(int i=0; i<20;i++){

//            NSLog(@”This isThread: %d”,i);

//        }

//    }];

 

//    NSOperationQueue * operationQueue=[[NSOperationQueue alloc]init];

//    //设置线程池中的并发数

//    operationQueue.maxConcurrentOperationCount=1;

//

//    NSInvocationOperation * invocation1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(threadOne) object:nil];

//    [invocation1 setQueuePriority:NSOperationQueuePriorityLow];

//

//    NSInvocationOperation * invocation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(threadTwo) object:nil];

//    [invocation2 setQueuePriority:NSOperationQueuePriorityHigh];

//    [operationQueue addOperation:invocation1];

 

//    [operationQueue addOperation:invocation2];

32.用多线程开启Nstimer提高精确度

//用多线程开启nstimer提高精确度

– (void)mutiThread

{

NSLog(@”Start NStimer”);

@autoreleasepool {

[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];

}

//获得当前的runloop,线程就停在这里

[[NSRunLoop currentRunLoop]run];

NSLog(@”after”);

}

– (void)timerAction:(NSTimer * )timer

{

i++;

NSLog(@”Print NSTimer”);

if (i==5) {

[timer invalidate];

}

}

33.判断此页面是push,还是模态过来的

if (self.presentingViewController) {

NSLog(@”这个是模态过来的!”);}

34。等比例放大缩小视图

UILabel * la=(UILabel * )[self.view viewWithTag:908];

[UIView animateWithDuration:.5 animations:^{

CGAffineTransform transform=la.transform;

transform=CGAffineTransformScale(la.transform, 1.5, 1.5);

la.transform=transform;

} completion:^(BOOL finished) {
CGAffineTransform transform=la.transform;

transform=CGAffineTransformScale(la.transform, 0.5, 0.5);

la.transform=transform;

}];

35.清掉编译文件

~/Library/Developer/Xcode/DerivedData

模拟器清空编译

~/Library/Application Support/iPhone Simulator/

36.改变状态栏的颜色状态

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

[[UIApplication sharedApplication] setStatusBarHidden:NO];

37.给自己的项目中添加特殊的标示符号

http://patorjk.com/software/taag/#p=moreopts&h=0&v=1&f=优雅&t=V

38 清空某个文件夹

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *outputURL = paths[0];

[NSFileManager.new removeItemAtPath:outputURL error:nil];

[NSFileManager.new createDirectoryAtPath:outputURL

withIntermediateDirectories:YES

attributes:nil

error:NULL];

39. 在document下创建文件

NSString *writePath=[NSString stringWithFormat:@”%@/%@.txt”,stre,@”aaa”];

NSData *data = [@”” dataUsingEncoding:NSUTF8StringEncoding];//新文件的初始数据,设为空

[[NSFileManager defaultManager] createFileAtPath:writePath contents:data attributes:nil];//创建文件的命令在这里

40.layoutSubviews在以下情况下会被调用:

1、init初始化不会触发layoutSubviews

2、addSubview会触发layoutSubviews
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化
4、滚动一个UIScrollView会触发layoutSubviews
5、旋转Screen会触发父UIView上的layoutSubviews事件
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件

41.苹果审核加急通道

https://developer.apple.com/appstore/contact/?topic=expedite

51 .美化配置git log

$ git config –global alias.lg “log –color –graph –pretty=format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ –abbrev-commit –”
$ git lg
52.查看远程 git
git remote show origin
53.显示远程git仓库
git remote show
54.OC冒泡排序
//   NSMutableArray 自带排序方法

NSMutableArray *lastArrary = [NSMutableArray arrayWithArray:sinceArray];

[lastArrary sortedArrayUsingSelector:@selector(compare:)];

– (NSComparisonResult)compare:(NSNumber *)otherNumber

{

// 设置升 降序
return NSOrderedDescending;

}

// 冒泡排序
NSMutableArray *sinM_Array = [NSMutableArray arrayWithArray:sinceArray];

for (int x = 0; x < sinceArray.count -1; x ++) {

for (int y = x + 1; y < sinceArray.count – 1 -x; y ++) {

int leftNum = [[sinM_Array objectAtIndex:x] intValue];

int rightNum = [[sinM_Array objectAtIndex:y]intValue];

if (leftNum > rightNum) {

[sinM_Array replaceObjectAtIndex:x withObject:[NSNumber numberWithInt:leftNum]];

[sinM_Array replaceObjectAtIndex:y withObject:[NSNumber numberWithInt:rightNum]];

}

}

}
55.前后摄像头的切换

– (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position

{

NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];

for ( AVCaptureDevice *device in devices )

if ( device.position == position )

return device;

return nil;

}

– (void)backCarme:(UIButton *)button

{

NSArray *inputs = self.session.inputs;

for ( AVCaptureDeviceInput *input in inputs ) {

AVCaptureDevice *device = input.device;

if ( [device hasMediaType:AVMediaTypeVideo] ) {

AVCaptureDevicePosition position = device.position;

AVCaptureDevice *newCamera = nil;

AVCaptureDeviceInput *newInput = nil;

if (position == AVCaptureDevicePositionFront)

newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];

else

newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];

newInput = [AVCaptureDeviceInput deviceInputWithDevice:newCamera error:nil];

[self.session beginConfiguration];

[self.session removeInput:input];

[self.session addInput:newInput];

[self.session commitConfiguration];

break;

}

}

}
56.#pragma mark –获得视频的尺寸
-(CGSize)getImage:(NSURL *)url

{
NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]forKey:AVURLAssetPreferPreciseDurationAndTimingKey];

AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:url options:opts];

CGSize size = [[[urlAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize];

return size;

}

57.播放音频

// 导入框架 AudioToolbox.framework

NSString *path = [[NSBundle mainBundle] pathForResource:@”msgcome” ofType:@”wav”];

NSURL *url = [NSURL fileURLWithPath:path];

SystemSoundID soundId;

AudioServicesCreateSystemSoundID((CFURLRef)url, &soundId);

AudioServicesPlaySystemSound(soundId);

有用 kotlin 开发后端的吗?

目前只敢工具类用 kotlin,不知道 kotlin 和 spring 会不会有兼容上的坑,兼容 spring 各种注解么。 目前发现比较难受的是,数据类(DO, DTO)必须全部用可空,不然 fastjson 反序列化会有问题。 有生产环境用 kotlin 开发的老哥吗,目前有什么问题?

20 条回复  •  2021-03-31 13:00:48 +08:00     
1 rust   2 小时 13 分钟前 公司一个小项目用了 Ktor,开发确实爽,目前还没有发现什么问题.    
2 xuanbg   2 小时 10 分钟前 自从 get 了终*秘技 cv 大法,Java 语言啰嗦繁琐的弱点也就不存在了,反倒是隐隐成了优势。所以 kotlin 什么的也就没有吸引力了    
3 zoharSoul   2 小时 8 分钟前 有, json 序列化建议用 gson, 和 kt 配合的资料比较多    
4 yazinnnn   2 小时 7 分钟前 json 现在在用 moshi 用 kotlin 可以尝试一下其他东西,比如 quarkus vertx 啥的    
5 micean   2 小时 0 分钟前 兼容旧系统的话,带问号是必要的。 所有的 pojo 用 IDEA 自带的.java 转.kt 就行 kotlin 目前*主要的问题在于 debug 反编译依赖 source,异常打印 stack 的行号不那么准    
6 zerofancy   1 小时 55 分钟前
毕设项目都是 Kotlin,目前遇到过两个奇怪的问题。

1. 同时有 Java 和 Kotlin 的 RestController,Java 的找不到
2. 类型推断好像有点问题

有如下代码:

“`kt
val gridFsFile: GridFSFile? = gridFsTemplate.findOne(Query(Criteria.where(“_id”).`is`(id)))
“`

idea 提示我

“`
‘gridFsFile’ is always non-null type
“`

很明显 gridFsTemplate 是可空的,甚至在接口 GridFsOperations 中已经标注了  。
尝试加入判空逻辑:

“`
if (gridFsFile == null) {
// do something
}
“`

idea 提示:

“`
No method ‘equals(Any?): Boolean’ available
“`

猜想是不是 Kotlin 调用 java 都会有这样问题,结果未能在 demo 项目中复现。
目前用这样的方式判断,原理不明:

“`kt
if (gridFsFile === null) {
// do something
}
“`

7 anke1938   1 小时 55 分钟前 两年前小公司用的纯 kotlin 后端 开发的 web 后台 / 小程序后台 用起来还是很爽的 没啥特别的坑 或者没怎么遇到    
8 hantsy   1 小时 52 分钟前 你多少年没用 Spring 了?
Spring 5.0(2017 年) 开始, 除了 Reactive,Kotlin 就是*重要的特性之一,Spring 对 Kotlin 进行深度集成(远超过之差的 Groovy 语言支持)。
针对很多 Kotlin 特性很多优化,例如,不必声明 open, data class 可以用于 JPA Entity 等。

Kotlin DSL 声明 beans 定义,安全 (参考 Spring 中 BeanDefinitionDSL )等。

val beans = beans {
bean {
CommandLineRunner {
println(“start data initialization…”)
val posts = ref<PostRepository>()
posts.deleteAll()
.thenMany<Post>(
posts.saveAll(
arrayListOf(
Post(null, “my first post”, “content of my first post”),
Post(null, “my second post”, “content of my second post”)
)
)
)
.log()
.subscribe(
{ println(it) },
{ println(it) },
{ println(“data initialization done…”) }
)
}
}

https://github.com/hantsy/spring-kotlin-dsl-sample/blob/master/reactive/src/main/kotlin/com/example/demo/DemoApplication.kt

现在 Spring 还有一个 Spring Kofu 孵化项目(提供完全 Kotlin DSL )。

val app = reactiveWebApplication {
configurationProperties<SampleProperties>(prefix = “sample”)
enable(dataConfig)
enable(webConfig)

listener<ApplicationReadyEvent> {
println(“start data initialization…”)
ref<PostRepository>().init()
}
profile(“foo”) {
beans { bean<Bar>() }
}
}

https://github.com/hantsy/spring-kotlin-dsl-sample/blob/master/kofu-reactive-mongo/src/main/kotlin/com/example/demo/DemoApplication.kt

9 optional   1 小时 51 分钟前 via iPhone   1 你不觉得 fastJson 比较坑。。。    
10 wellsc   1 小时 50 分钟前 借楼问一个 kotlin 的 protobuf grpc 的库    
11 hantsy   1 小时 50 分钟前 @zerofancy Spring Data 一般中 Template, repository 都有写 Kotlin 扩展。估计那 GridFsTemplate 没有处理。    
12 hantsy   1 小时 48 分钟前 @optional 在 Spring 3 。x 就开始提供了内容协商机制,为什么要用 FastJSON 这种东西???实在不明白。    
13 ChangQin   1 小时 10 分钟前 via iPhone @rust ktor+1    
14 zoharSoul   1 小时 3 分钟前 @zerofancy gridFsTemplate.findOne 返回的是 nullable 的吗?    
15 loshine1992   1 小时 0 分钟前 用 moshi 或 kotlin-serialization    
16 xmumiffy   56 分钟前 via Android 建议换掉 fastjson 另外也可以混用 java 至少我这 data class 都是用 java 的,kotlin 的 data class 非常不好用    
17 Kasumi20   42 分钟前 没有发现 Kotlin 不支持 IoC 和 AOP,所以 Kotlin 和 Spring 百分百兼容。 至于什么反序列化的如果是先构造一个空对象,当然会有问题。    
18 boris93   34 分钟前 via iPhone 正在用 Kotlin+Spring Boot+Webflux json 序列化反序列化用的 jackson 目前没啥问题 话说干嘛要用 fastjson 呢?框架自己序列化反序列化用自带的 jackson 就行了啊,也就稍微配置一下的事 偶尔用 gson 也能搞定    
19 youngxhui   27 分钟前 via Android @wellsc grpc 官方有的    
20 wellsc   9 分钟前 via iPhone @youngxhui protobuf 我没找到好用的

关于学习Python的一点学习总结

关于学习Python的一点学习总结

27.创建和使用字典:字典由键及其相应的值组成,这种键值对称为项(item)
方法一:

>>> name={‘Hongkong’:’45’,’shanghai’:’67’,’guizhou’:’89’}
>>> name
{‘Hongkong’: ’45’, ‘shanghai’: ’67’, ‘guizhou’: ’89’}

方法二:

>>> item={(‘hongkong’,’45’),(‘guizhou’,’67’),(‘shanghai’,’89’)}
>>> name=dict(item)
>>> name
{‘hongkong’: ’45’, ‘shanghai’: ’89’, ‘guizhou’: ’67’}
>>> name[‘shanghai’]
’89’

方法三:

>>> name=dict(first=’one’,shanghai=’67’,guizhou=’89’)
>>> name
{‘first’: ‘one’, ‘shanghai’: ’67’, ‘guizhou’: ’89’}
>>> name[‘first’]
‘one’
>>> name[‘guizhou’]
’89’

关于字典的一些基本操作:
1. len(d)返回字典d包含的项(键值对)数。
2.d[k]返回与键k相关联的值。
3.d[k] = v将值v关联到键k。 
4.del d[k]删除键为k的项。
5.k in d检查字典d是否包含键为k的项。

>>> name=dict(first=’one’,shanghai=’67’,guizhou=’89’)
>>> len(name)

>>> name[‘shanghai’]=78
>>> name
{‘first’: ‘one’, ‘shanghai’: 78, ‘guizhou’: ’89’}
>>> del name[‘first’]
>>> name
{‘shanghai’: 78, ‘guizhou’: ’89’}
>>> ‘guizhou’ in name
True

注意:将一个字符赋值给列表是不可以的;而将一个字符赋值给字典是可以的。
例如:

` >>> item=[]
>>> item[2]=’guizhou’
Traceback (most recent call last):
File “<pyshell#43>”, line 1, in <module>
item[2]=’guizhou’
IndexError: list assignment index out of range
——————————————————-
>>> item={}
>>> item[2]=’guizhou’
>>> item[2]
‘guizhou’

遍历点击下拉树图标

遍历点击下拉树图标

发现有下级菜单的图标,都有一个特点,放到css里面了。

然后进行循环,点击一个展开后 需要重新定位这样不会有重复的。这里有个特殊的,是从0开始的,循环的时候要注意。

#循环点击左侧树状图 先遍历点下拉图标
ele_icon=driver.find_elements_by_css_selector(‘.aty-tree-node-hd .aty-tree-node-trigger’)
css=’.aty-tree-node-hd .aty-tree-node-trigger’
left_list=driver.find_elements_by_css_selector(css)
print(f”’我在外面{len(left_list)}”’)
for i in range(0,len(left_list)+1):
driver.find_elements_by_css_selector(css)[i].click()
left_list = driver.find_elements_by_css_selector(css)
print(f”’我在里面{len(left_list)}”’)
time.sleep(2)
print(i)
再附上一个  固定两个层级的代码–备用

import time
import self
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver

# 判断元素是否存在的方法
def isElementExist(ele_icon):
flag=True
# browser=self.driver
try:
driver.find_element_by_xpath(ele_icon)
return flag
except:
flag=False
return flag

if __name__ == ‘__main__’:

driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(30)
first_url = ‘http://172.18.65.1111111136:8081/#/query/1’
driver.get(first_url)
#点击到编辑查询界面
driver.find_element_by_xpath(‘//*[@id=”app”]/div[1]/div[2]/div[2]/div/div[3]/div[1]/div/div[2]/span’).click()
driver.find_element_by_xpath(‘//*[@id=”app”]/div[2]/div/div[2]/div[1]/div[1]/button/span’).click()

#循环点击左侧树状图
left_table=driver.find_elements_by_css_selector(‘#jsTreeContain>.aty-tree-node’)
index=len(left_table)
for i in range(1,index+1):
try:
#*个层级 这里有可能会有多个层级,一般是一个 //*[@id=”jsTreeContain”]/li[1]/h3/span[2]
ele=driver.find_element_by_xpath(‘//*[@id=”jsTreeContain”]/li[‘+str(i)+’]/h3/span[2]’)
ele_icon=driver.find_element_by_xpath(‘//*[@id=”jsTreeContain”]/li[‘+str(i)+’]/h3/span[1]’)
flag=isElementExist(ele_icon)
ele_icon.click()
print(‘已展开下级菜单’.center(50,’-‘))
time.sleep(1)
# 第二个层级 #jsTreeContain .aty-tree-node-content >.aty-tree-node
ele2 = driver.find_elements_by_css_selector(‘#jsTreeContain .aty-tree-node-content >.aty-tree-node’)
num = len(ele2)
print(f”'{i}组:{ele.text}里有{num}个表”’)
for m in range(1, num + 1):
ele_inner = driver.find_element_by_xpath(‘//*[@id=”jsTreeContain”]/li[‘ + str(i) + ‘]/ul/li[‘ + str(m) + ‘]’)
ele_inner.click()
print(f”’第{m}个表为:{ele_inner.text}”’)
time.sleep(0.5)

except NoSuchElementException:
driver.find_element_by_xpath(‘//*[@id=”jsTreeContain”]/li[‘+str(i)+’]/h3/span’).click()

LeetCode——反转字符串中的元音字母

LeetCode——反转字符串中的元音字母

LeetCode——反转字符串中的元音字母
题目描述:
编写一个函数,以字符串作为输入,反转该字符串中的元音字母。

示例 1:

输入:“hello”
输出:“holle”
示例 2:

输入:“leetcode”
输出:“leotcede”

提示:

元音字母不包含字母 “y” 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-vowels-of-a-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

双指针法:
首先我们将所有元音字母的小写和大写都存储在一个列表yy中,便于判断遇到的字符是否是元音字母。
然后定义两个指针,一个指向字符串首端(start),一个指向字符串末端(end)。
我们遍历整个字符串,循环条件是start < end,在循环中,我们首先判断start和end指向的是否是元音字母,如果不是则更新指针的位置,如果都是元音字母则交换两个字母的位置。
因为我使用的是python语言,所以需要注意字符串是无法修改的,我们需要将s转换为列表,再对列表进行操作,结束后再把该列表转换回字符串,*后返回字符串s。

双指针法python代码:

class Solution(object):
def reverseVowels(self, s):
“””
:type s: str
:rtype: str
“””
yy = [‘a’, ‘e’, ‘i’, ‘o’, ‘u’, ‘A’, ‘E’, ‘I’, ‘O’, ‘U’]
s_list = list(s)
start = 0
end = len(s) – 1
while start < end:
if s[start] not in yy:
start += 1
if s[end] not in yy:
end -= 1
if s[start] in yy and s[end] in yy:
s_list[start], s_list[end] = s_list[end], s_list[start]
start += 1
end -= 1
s = ”.join(s_list)
return s

4款开源云计算框架和工具简介

本文讲的是4款开源云计算框架和工具简介,【IT168 资讯】1、Enomalism (http://www.enomaly.com/) 云计算平台。Enomalism 是一个开放源代码项目,它提供了一个功能类似于 EC2 的云计算框架。Enomalism 基于 Linux,同时支持 Xen 和 Kernel Virtual Machine(KVM)。Enomalism 提供了一个基于 TurboGears Web 应用程序框架和 Python 的软件栈。
2、Euclyptus (http://eucalyptus.cs.ucsb.edu/) 项目(Elastic Utility Computing Architecture for Linking Your Programs To Useful Systems)是 Amazon EC2 的一个开源实现,它与商业服务接口兼容。和 EC2 一样,Eucalyptus 依赖于 Linux 和 Xen 进行操作系统虚拟化。Eucalyptus 是加利福尼亚大学(Santa Barbara)为进行云计算研究而开发的。您可以从该大学的网站上下载它,或者通过 Eucalyptus Public Cloud 体验它,不过后者有一些限制。
3、10Gen (http://www.10gen.com/) 它既是一个云平台,又是一个可下载的开放源代码包,可用于创建您自己的私有云。10gen 是类似于 App Engine 的一个软件栈,它提供与 App Engine 类似的功能 — 但有一些不同之处。通过 10gen,可以使用 Python 以及 JavaScript. 和 Ruby 编程语言开发应用程序。该平台还使用沙盒概念隔离应用程序,并且使用它们自己的应用服务器的许多计算机(当然,是在 Linux 上构建)提供一个可靠的环境。
4、NimBus (http://workspace.globus.org/) 呵呵,网格中间件Globus的作品,从*早的Virtual Workspace演化而来,提供与EC2类似的功能和接口。
另外我们还有一个补充,云计算怎么能没有BOINC呢~
5、BOINC(http://boinc.berkeley.edu/)   BOINC 的英语全称是 Berkeley Open Infrastructure for Network Computing,直接翻译成中文的意思是:伯克利开放式网络计算。
BOINC 是一个分布式计算平台,使得各种分布式计算项目能够使用一个平台软件来运行。不同于传统的分布式计算项目(比如SETI@homeClassic,Folding@home)都有独立的内核和分布式程序,通过BOINC,协调不同的项目所能分配到的系统资源,都将变得非常方便。
BOINC 是由美国加利福尼亚大学伯克利分校(University of California -Berkeley)于2003年开发,通过多年时间、多个项目的测试,目前该平台已经较为成熟。伯克利方面之前曾成功运行 SETI@home项目6年多,取得巨大成功,吸引了五百多万用户的参加,完成了两百万CPU小时的计算量。BOINC平台的开发,很重要的一个原因是为了吸引更多用户加入更多的其他由实际意义的分布式计算项目,比如气候变化,药物开发等。
BOINC 的前景非常客观,有可能发展成一种业界标准,有了 BOINC 平台,分布式计算的开发和推广工作变得更加容易简便。而统一的界面,统一的方式将会大大方便新加入分布式计算的用户,而不必研究每个不同项目的参与方法、积分算法等。  BOINC 中文主页是http://boinc.equn.com/
补充知识:云计算的几大形式
1.SAAS(软件即服务)
这种类型的云计算通过浏览器把程序传给成千上万的用户。在用户眼中看来,这样会省去在服务器和软件授权上的开支;从供应商角度来看,这样只需要维持一个程序就够了,这样能够减少成本。Salesforce.com是迄今为止这类服务*为出名的公司。SAAS在人力资源管理程序和ERP中比较常用。
Google Apps和Zoho Office也是类似的服务
2.实用计算(Utility Computing)
这个主意很早就有了,但是直到*近才在Amazon.com、Sun、IBM和其它提供存储服务和虚拟服务器的公司中新生。这种云计算是为IT行业创造虚拟的数据中心使得其能够把内存、I/O设备、存储和计算能力集中起来成为一个虚拟的资源池来为整个网络提供服务。
3.网络服务
同SAAS关系密切,网络服务提供者们能够提供API让开发者能够开发更多基于互联网的应用,而不是提供单机程序。
4.平台即服务
另一种SAAS,这种形式的云计算把开发环境作为一种服务来提供。你可以使用中间商的设备来开发自己的程序并通过互联网和其服务器传到用户手中。
5.MSP(管理服务提供商)
*古老的云计算运用之一。这种应用更多的是面向IT行业而不是终端用户,常用于邮件病毒扫描、程序监控等等。
6.商业服务平台
SAAS和MSP的混合应用,该类云计算为用户和提供商之间的互动提供了一个平台。比如用户个人开支管理系统,能够根据用户的设置来管理其开支并协调其订购的各种服务。
7.互联网整合
将互联网上提供类似服务的公司整合起来,以便用户能够更方便的比较和选择自己的服务供应商。

用 Vulkan 渲染写一个 Android GPUImage

说的 GPUImage 相信大家都不陌生,GPUImage 是做滤镜、渲染、特效*主流的框架之一,被广泛应用在短视频应用中。

GPUImage 目前还是采用 OpenGL 进行渲染的,可随着技术的发展进步,iOS 系统都开始抛弃 OpenGL 拥抱 Metal 了,Android 也推出了 Vulkan 渲染机制。

关于 Vulkan,大家可能会有点陌生,它和 OpenGL 一样也是跨平台的渲染接口,就是学习成本高了一点,调用流程麻烦了一点,但还是可以掌握的~~~

而且一旦掌握了 Vulkan, 再去看 Metal,或者 Windows 平台下的 Direct3D,就会发现它们有很多共通之处的,很多概念都是可以互相借鉴的,就好比编程语言一样,掌握了 Kotlin 再去看 Swift 感觉就傻傻分不清楚了。

这次要介绍的就是用 Vulkan 实现一个 Android GPUImage 了。

我已经实现了大部分的代码,组建了基本的渲染链机制,复刻了一些特效,具体可以看代码详情:

代码地址如下,欢迎 Star !!!

https://github.com/glumes/Vulkan-GPUImage

想要后续添加特效也是非常方便的,以曝光特效为例:

static const char *shader =
        "#version 400\n"
        "#extension GL_ARB_separate_shader_objects : enable\n"
        "#extension GL_ARB_shading_language_420pack : enable\n"
        "layout (binding = 0) uniform sampler2D tex;\n"
        "layout (location = 0) in vec2 texcoord;\n"
        "layout (location = 0) out vec4 uFragColor;\n"
        "layout (push_constant) uniform exposure {\n"
        " float exposure;\n"
        "} pushVals;\n"
        "void main() {\n"
        "    vec4 textureColor = texture(tex,  texcoord); \n"
        "   uFragColor = vec4(textureColor.rgb * pow(2.0,pushVals.exposure),textureColor.w);\n"
        "}";

class ExposureFilter : public VulkanFilter {

public:
    ExposureFilter() : VulkanFilter() {
        pFragShader = shader;
        pushConstant.resize(1);
        pushConstant[0] = exposure;
    }

    virtual void setProcess(uint32_t process);

protected:

private:
    float exposure = 1.0f;
};

首先实现对应的 Shader,然后对应特效类继承自 VulkanFilter,如果特效没有需要更新的参数,可以不用 pushConstant 。

如果有的话把 pushConstant 的长度修改为参数的个数,每个参数对应 shader 中推送常数的值即可。

然后在 setProcess 里面修改对应的 pushConstant 值:

void ExposureFilter::setProcess(uint32_t process) {
    pushConstant[0] = FilterUtil::getProcess(process,-10.0f,10.0f);
}

在应用中拖动 SeekBar,就可以更改对应的常量值了,从而修改 Shader 效果,对于简单的特效,基本上不用五分钟就可以添加一个新的效果了,很多封装工作都放在 VulkanFilter 里面了。

在实现上采用的是多 RenderPass 的方式,其实也可以用多 Subpass 的方式,但是不好做效果切换,干脆就多 RenderPass 了,其实也可以两者混合。

代码写的不是特别优雅,后面持续优化了,各位走过路过不要错过,目前全网还搜不到 Vulkan 做 GPUImage 相关的实现呢,算是开张了,觉得有帮助就点个 Star 呀~~~

12 条回复  •  2021-03-09 22:56:23 +08:00

1 visionsmile   21 天前 老哥牛皮,已 star

2 glumess   21 天前 @visionsmile 感谢老铁~~

3 codehz   21 天前 via Android Vulkan 在移动平台 /linux 桌面海星,windows 上驱动还是问题很大。。。

4 neoblackcap   21 天前 @codehz windows 平台就老实用 DX 啦,用 vulkan 找不自在么?

5 MCVector   21 天前 @codehz @neoblackcap Vulkan 在 Windows 下的驱动似乎还行呀。我用的 GTX 1070 基本上 Vulkan 1.2 的 feature 都能用,Ray tracing pipeline 的大部分 extensions 都支持

6 MCVector   21 天前 如果用 subpass 的话像 Gaussian blur 这种需要读周围 pixel 的 pass 应该就用不了了吧?这样直接用 renderpass 可能会更灵活一些

7 neoblackcap   21 天前 @MCVector 可能看是哪一家吧,不过 Vulkan 是二等公民,肯定不如 DX 好使。

8 MCVector   21 天前   1 @neoblackcap 我不认为 DX12 在 Windows 下能做的 Vulkan 做不了。据我所知基本上支持 DX12 的显卡在 Windows 下都支持 Vulkan 。所以我认为 Vulkan 是二等公民的说法是不成立的。

9 TSai2019   21 天前 via Android filter-> filter 没有? two input 也没有,离完整 GPUImage 还差不少

10 glumess   21 天前 @TSai2019 filter -> fitler 应该有了啊,采用两个 renderpass 的方式实现的,two input 还在想怎么搞更好…

11 glumess   21 天前 @MCVector 高斯模糊的 shader 应该可以吧,就是 shader 里面的操作呀

12 MCVector   20 天前 @glumess 哈哈我之前也是这么想的。 如果用 subpass 的话在当前的 fragment shader 里只能读前一个 subpass 输出的同一个 fragment (subpassLoad()), 而不是像传统的 renderpass 一样可以用 uv 读。高斯模糊需要周围像素的信息所以在这种情况下会有限制。 Subpass 存在的原因是告诉 GPU 不需要等到整张图片都处理完了再开始下一个 pass 的处理,而是当前 fragment 处理完了下一个 pass 就可以操作这个 fragment 了。这样可以减少一些 overhead,同时也限制了只能操作当前 fragment 。

服务器性能配置要点总结

一般来说,服务器性能主要由三部分决定:

1.服务器的硬件配置

2.服务器操作系统

3.应用程序

服务器硬件配置主要有:

(1).CPU

一般来说CPU的数量越多,主频越高,那么服务器的性能也就会越好。在实际测试过程中,如果在大压力下持续观察CPU的使用率很低,那么CPU的资源基本上是可以满足服务器要求的。这样的情况其实是有点浪费CPU资源的,比较理想的情况是压力不大的时候CPU利用率比较低,压力上来之后CPU利用率保持在60%-70%。大部分的CPU在同一时间内只能运行一个线程,但是超线程的处理器可以在同一个时间运行多个线程,我们可以利用处理前超线程特性提高系统性能。虽然采用超线程技术能同时执行两个线程,但它并不象两个真正的CPU那样,每个CPU都具有独立的资源。当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲置后才能继续。因此超线程的性能并不等于两颗CPU的性能。

(2).RAM

内存的大小也是影响服务器性能的一个重要因素。内存太小,系统进程要被阻塞,应用程序会变得缓慢,甚至是失去响应;如果太大的话,也是造成一种浪费。Linux系统中采用物理内存和虚拟内存两种方式,使用虚拟内存可以缓解物理内存的不足,但是如果占用过多的虚拟内存的话,应用程序的性能会明显的下降。

(3).网络宽带

网络带宽的大小限制了客户端与服务器交互的流量,相对其他硬件资源,网络带宽在价格上更贵。这需要我们合理预估服务器的可服务器能力,需要占用的带宽资源。

(4).硬盘

以前硬盘多是机械方式运作的,主要体现在硬盘读写前寻找磁道的过程。硬盘自带的读写缓存大小,对于硬盘读写速度至关重要。读写速度快的硬盘,通常都带有较大的读写缓存。硬盘的寻道过程是机械方式,决定了其随机读写速度将明显低于顺序读写。在我们做系统设计和实现时,需要考虑到硬盘的这一特性。

操作系统:

(1).操作系统

当前主流的服务器操作系统则主要分为:Windows server、UNIX、Linux、NetWare这四大阵容。不同的系统有不同的特点,要根据情况来判断
Windows server是用户群体*大的服务器系统,不得不多做介绍。旗下又分为:Winnt4.0、Win2000、Win2003、Win2008、Win2012。

Win2000则是Winnt原有完整的内核上进行开发的,对多任务的处理能力有了大幅的提升,管理以及其他功能更加全面,但是系统的稳定性和安全性被削弱了。微软也停止了对win2000的销售和升级服务;win2003在操作的易用性上进行了升级,安全性是目前所有的windows server系统中*高的,线程处理能力、硬件的支持、管理能力都有了大幅的提升,是目前服务器操作系统中主流的操作系统之一。不过由于更多功能的加入,使得win2003的处理能力有所下降。win2008添加了一些特性和策略,以及多了server 2008 r2b版本,运行速度有所加强,但是稳定性有所欠佳。也是主流系统之一。*后就是win2012,目前微服务器操作系统中*高的版本,同时也有r2版本,全面的升级,对应win8内核优化而来,但是,对一些老牌软件应用的兼容性,以及稳定性还是欠佳的。如果说            Windows server是为单用户设计的,那么UNIX则是为多用户而生的。支持大型文件系统和数据库,系统的安全性、稳定性、以及引用软件有着Windows server无法比拟的优势。但是操作界面欠人性化,相关操作管理技未得到推广,使得雇佣维护人员的成本非常高。
Linux是基于UNIX系统开发修补而来,免费、开源、使得其稳定性、安全性、兼容性非常高,对于商业服务器是首选。但是仅凭开发的源代码,使得很多服务器管理人员对其喜爱有加。
NetWare对服务器硬件的要求*低,而且对于网络的组件也有着先天的优势,能够支持无盘工作站,也能支持非常之多游戏软件的开发环境搭建,还能节省很多成本,常用户网络教学、游戏大厅、金融系统等。但是同样是需要手工敲入命令来实现操作指令的。而且系统多年来也没有更深层次的更新,使得部分软件的支持与其他新型应用的兼容性有所欠佳。

(2).操作系统选型原则

一般来说,个人用户或者实验用户,选用windows操作系统比较普遍,人性化的界面设计使得操作简单,而且网上能找到大量的资料来参考。商业或者对服务器性能要求较高场合一般使用Linux或者UNIX.

应用程序本身:
对于应用程序本身的设计来说,只要选用合适的数据结构和内存操作方式,那么至少在性能上差距不是很大,避免对常用内存数据的多次创建和释放。也可增加服务器的性能。

linux服务器磁盘爆满分析

项目场景:
linux虚拟服务器

问题描述:
linux服务器使用时间长后,导致系统登录失败(磁盘爆满)。

原因分析:
登录失败:redis服务无法访问。启动redis后,redis的log日志显示启动失败,原因是服务器磁盘爆满,无法加载数据。
爆满原因:查询服务器大容量文件夹,删除大文件。

解决方案:
1、应用命令df -h ,查询服务器磁盘应用情况
%title插图%num

2、应用命令du -h --max-depth=1,查询大文件目录,发现user目录*大

%title插图%num

3、进入usr,继续查询大文件目录

%title插图%num

4、*后定位到/usr/local/naocs/bin/log下,执行命令ls -lh发现log下44G日志文件,删除即可。
5、针对naocs日志文件日增长过大,采取对应配置。

混合云的那些事,如何做到让公有云和私有云实现1+1>2

云计算在2016年有了*大的增长。一方面,AWS、阿里云等大型公有云厂商的云计算收入呈爆发式增长且*对值数据可观;另一方面,通过持续市场培育,云计算的价值逐步被各国政府所认可。很多大型企业也纷纷发力云计算,传统IDC采购出现增长拐点。各种声音不断提醒人们,云计算不再是雷声大雨点小的噱头,而是成为大中小企业不可或缺的基础设施。2017年,云计算真正落地的话题逐渐成为业界讨论的热门话题。

当前,私有云和公有云相争的热潮渐弱,融合两者优势的混合云开始逐渐释放巨大的市场潜力。混合云的背后不再是厂商,而是一种混合IT架构,是公有云与私有云的集成。因此,如何构建基于云计算的混合IT架构,成为CIO和CTO避不过的问题。

本文我们首先回顾公有云与私有云的优缺点,之后聊聊到底什么是混合云、使用场景与产品有哪些,紧接着重点分享架构核心思路与技术实现原则,*后来说说用户到底能在混合云平台上做些什么事。

公有云与私有云优缺点

如何做到让公有云和私有云实现

笔者曾经在公有云厂商和私有云厂商都有过研发经历,对公有云和私有云各自能带来的优势和局限都有比较深入的体会。对于市场来说,公有云和私有云都有它们无法被取代的优势,*好的选择就是根据自身业务结合二者,这一点也已经得到了市场的普遍认同。

混合云的定义与使用场景

混合云的定义

对于混合云的定义,中国信息通信研究院曾经提出过观点,是必须要同时有公有云和私有云,这也是大多数厂商和用户的认知。笔者认为,这样的定义只是物理上的堆彻,两者之间如果不能发生化学反应,并不是真正的混合云,也无法催生出创新型应用,无法真正帮助用户提高业务价值。混合云不是简单的对公有云和私有云进行1+1=2的运算,而一定要让它们产生大于2的价值。

虚拟化与云计算的区别

为了更好的理解这点,让我们来回顾一下虚拟化与云计算的区别。虚拟化是一种技术,而云计算则是基于虚拟化技术之上的升华,它让用户能够管理一个数据中心及其增值服务,将IT资源以服务的形式交付给用户,从而让用户能够专注于业务而不是IT资源。虚拟化帮助用户提高硬件的资源利用率,而云计算则帮助用户提高整个数据中心的整体资源利用率,这中间也包括软件、网络、存储甚至于人力的资源利用率。

那么,混合云作为云计算的一种形态,它要给用户带来的价值,并不是简单的把公有云和私有云堆彻在一起,而是让两者产生碰撞,从而提高用户跨云的资源利用率,催生出新的业务。

混合云应该是帮助用户接管跨云、跨地域的IT基础设施,把用户花在底层实现上的精力解放出来,甚至可以反复尝试业务在公有云与私有云之间的组合模式而不用关心底层实现细节,从而*大提高用户的生产力和降低业务的试错成本。

故我们可以看到,混合云不是简单的一张皮,也不是完成连通的其中一个细节,它是包含了公有云各资源和产品以及私有云各资源和产品的一个有机整体系统。因此,同时存在公有云与私有云只是混合云的必要条件,而非充要条件。那么还需要有什么呢?

如何做到让公有云和私有云实现

混合云在数据中心的价值

我们先来看看用户想要什么。在同时存在私有云和公有云的情况下,用户自然会想到如下场景:

  • 将私密数据放在本地,公开访问入口放在公有云。
  • 高峰期能利用公有云的资源进行无限拓展。
  • 本地业务能加密备份在公有云。
  • 多数据中心通过公有云实现星形连通。
  • 开发测试在本地快速迭代,生产业务放在公有云。
  • 内部业务放在本地数据中心,对外开放业务放在公有云,完全摒弃掉公有云控制台,在本地闭环完成所有操作。

事实上由于现在真正实施混合云的用户非常之少,还有大量未知的创新等待着聪明的用户去发掘。

那么如何来实现这些场景呢?在单一的私有云或者公有云场景下,用户不需要关心底层是如何实现的,他们使用镜像创建虚拟机,使用快照备份磁盘,搭建多个二层或三层网络并在平台上自定义路由和安全组来进行通信,使用Autoscaling或其他编排系统来进行资源自动编排,并在一个多租户场景下工作。

那么在混合云的场景下,我们则抽象出如下实现手段:

  • 创建和管理(包括运维)虚拟机而不关心镜像在哪里或虚拟机在哪里。
  • 创建或备份磁盘而不关心磁盘在哪里或备份在哪里。
  • 搭建网络并定义它的通信目标,无论是在本地数据中心或者公有云。
  • 自由编排资源,无论是在本地数据中心或者公有云。
  • 统一而不是割裂的帐户管理体系。

混合云产品主要基于灾备、网络互联和多云管理

市场对混合云的声音日益庞大,但目前混合云并没有真正的标准,也没有准确的定义。目前的混合云产品主要基于以下三类:

基于灾备产品

厂商通过用户自定义的策略将用户的数据备份到公有云,并可以恢复到本地。这主要是一些存储厂商提供的产品,如英方云、数腾云、XSKY等。

基于网络互连产品

厂商主要做网络服务,帮助用户快速完成本地数据中心与公有云的对接服务,达到互联互通的目的。这主要是一些网络厂商提供的产品,如网银互联、游驰、犀思云等。

多云管理产品

厂商主要做多云管理产品,致力于帮助用户在一套管理平台上对多个公有云或私有云产品进行管理层面服务,增强用户的一致性体验,帮助用户更好管理自己的云计算资源,并提供部分运维及PaaS服务。这主要是一些CMP厂商提供的产品,如Fit2Cloud、RightCloud、行云管家等。

我们可以看到,以上几类产品分别能够帮助用户实现基于私有云和公有云的一种或多种场景。

混合云架构核心思路:连接一切IT,无缝混合体验

了解混合云的定义、使用场景和产品之后,我们来看看具体实现过程。作为云计算厂商或开发者,应该对功能矩阵非常熟悉。云计算厂商之间的比拼一个重要的层面就是功能矩阵的较量。

正是IaaS层提供了成百上千的功能点,才让用户得以轻松地进行各项业务开发。

在今天私有云和公有云都各自有了相似的巨大功能矩阵,我们仔细思考可以得出结论,大量的功能都是不需要跨云的,例如GPU直通,只需要分别在私有云端和公有云端实现,作为混合云服务商,只要把这个功能展现出来即可。但仍然有许多跨资源的关键业务,是需要混合云厂商提供帮助的。

例如公有云上的路由,这条路由可以指向公有云VPC,也应该可以指向本地数据中心的VPC。类似这样的业务,是混合云功能的重点。

ZStack作为开源的国产自研IaaS软件,进行混合云的研发己经有一段时间。根据经验来看,*重要的核心思路就是保证混合云产品拥有连接一切的能力和无缝结合的能力。

连接一切IT

连接一切IT的本质是实现数据层面的打通,这是实现混合云一切场景的前提条件。数据层面打通在今天主要是三个打通:帐户打通、网络打通、存储打通。

帐户打通:使用一套帐户管理公有云和私有云,即以私有云自身的帐户体系和多租户权限管理为主体,公有云的AK权限只是辅助。将公有云AK绑定到私有云的相应帐户上,巧妙结合私有云和公有云各自的权限体系,可以实现无比灵活的多租户场景,建立起满足企业要求的帐号管理体系。

网络打通:网络打通即指能够将本地私有云的网络和公有云的网络在二层或者三层上连通起来,实现各种自定义的网络结构,如跨数据中心连通用户的两个子业务部门等。由于网络配置非常复杂,中间涉及到多种设备,因此网络能力往往是云计算厂商综合能力的体现。

存储打通:私有云和公有云之间通常很难直接将存储系统连接或扩展。所以我们指的存储打通,是在快照和镜像层面的打通。即虚拟机或容器的快照和镜像,能够在私有云和公有云之间自由迁移,这种应该是代价*小的,如完全的增量迁移,或实时迁移等。从而可以使本地制作镜像模板直接在公有云上创建云主机,或反之。

在实现以上三个打通后,用户就可以基于混合云实现很多自定义网络,比如连接多个本地数据中心和多个公有云VPC,自由组合成星形、环形、网形等业务所需要的网络,并让镜像快照在各地之间共享。这一切的配置都可以在分钟级完成,大大加速了业务创新,彻底取缔了信息孤岛,实现全国一张网,一个系统。

无缝混合体验

无缝结合更多是从控制面的设计来讲,达到用户所有的云资源,不论是在公有云还是私有云,能得到一视同仁的处理。事实上由于公有云和私有云平台天生模型的不一致(Azure stack这样的平台例外),很难强行把它们用相同的界面和逻辑来进行操作,而类似region,availability zone这样的概念,更是无法对用户屏蔽但私有云很难存在的概念。

所以在实现上,好的无缝体验,应该是让公有云和私有云的资源在同一个平台上操作,它们的操作内在逻辑是完全一致,而非相互割裂。此处以创建云主机和创建专线连接为例。

创建云主机

当我们创建私有云主机时,需要选择网络、主存储、镜像、资源规格、可能还有物理机、集群等。而创建公有云主机时,需要选择镜像、安全组、网络、计算规格、可能还有可用区等。相比之下,公有云不可能看到物理机,而私有云不可能看到可用区,两者的计算规格和网络的模型也可能完全不同。

我们可以将它们放在同一个页面,但一个页面还是两个页面,对用户的操作路径来说都是一步,所以意义不大。真正有意义的是让用户在操作过程中感受到完全的无缝。即创建的过程是完全相同的,所有资源都不需要到公有云控制台去进行额外的查找,本地就能闭环地完成所有操作。

创建专线连接

这是典型的跨云资源操作。连接时需要选择本地网络与公有云网络,这些选择都应该是在平台上直接进行选择或创建(例如创建一个边界路由器等),然后点击连接,混合云平台自动完成剩下的连接工作。不需要用户登录到各个云平台查看类似id、网关、cidr等属性。从体验上来说,用户的直观感受就是选择了两个网络,就创建了连接。而这背后,则是混合云平台进行了大量的建模和数据同步工作。

通过以上两个示例可以看到,因为公有云和私有云之间的模型天生是有部分差异,因此无感知的混合云并不是要强制用户使用相同的模型去套用不同的云平台,而是在建立好对应的模型后,在后台使用完全相同的逻辑去处理它们。而从API设计上来讲,私有云和公有云资源的操作分属不同的API,但它们的语义、参数都是非常相近的。

混合云架构的具体技术实现原则

在定义了连接一切、无缝体验之后,技术层面在实现它们时有哪些需要注意呢?在此提供以下一些设计原则以供大家参考:

建立完整数据模型

我们在设计私有云平台时,会建立完整的私有云数据模型,如快照、磁盘、云主机、VPC、路由器等,它们之间存在千丝万缕的关系。同样,在设计公有云平台时,也要建立相应的数据模型。那么在设计混合云时,就必须同时建立这二者的模型,并且必须是完整的,因为存在许多关联关系,导致缺少任意一个资源的模型,都不能算完整。

布设虚拟ID

公有云资源映射到本地,成为一个虚拟资源。我们需要给每一个公有云资源分配一个本地的虚拟ID,而不能直接使用公有云的ID。因为在多租户的场景下,公有云的ID在本地并非是唯一的,只有本地的ID才能保证它的唯一性。

触发同步

由于存在映射关系,所以需要进行同步,同步可以是主动触发,也可以是被动触发的。同步的目的:一是让用户在公有云控制台上做的操作也能及时反映到本地,二是保证所有的读写操作都在本地进行,让操作的流畅程度达到毫秒级。正是有了同步,混合云资源的操作速度,可以比直接在公有云控制台上操作快了两个数量级,这让用户可以放心地做更多的事。

遍历资源模型

云计算的资源模型是树状的结构,因此任何操作都需要遍历这棵树,以便让它的所有父子资源和相关资源都能得到及时的变更。例如删除或同步一个VPC,需要遍历它下面所有的交换机、安全组、云主机、EIP、NAT网关、路由表、安全规则等等,进行相应的变更,出现失败时要能按顺序进行回滚,保证操作的原子性。又比如删除一个本地网络,需要遍历所有指向它的资源,如路由设备,监控指标等等,进行路由的变更,和网络拓扑关系的自动适配,而不是简单删除就可以,下图为*连接的混合云数据模型。

 

混合云*连接的数据模型

区分逻辑和真实操作

对公有云资源的操作都必须区分逻辑操作和真实操作,方便管理员的管理。比如有的用户只能逻辑上删除一个公有云网络,而不允许真实删除公有云网络。又比如对可用区这种概念,用户只能逻辑性地清除它以及它的子资源,而不能真实删除一个可用区,因为这是公有云的固有属性。

升级原则

对于混合云产品来说,私有云的部分是可以随产品升级而升级的,但公有云部分的升级,则可能影响到产品的稳定性。因此要注意两个原则:

一是对公有云的操作失败范围要尽量控制在可以控制的范围内,比如错误或数据结构控制在有限的package内,避免公有云API的调用失败影响到产品整体流程。

二是对公有云上有可能变更的行为和资源保持弹性和可降级处理,比如公有云上的可用区是有可能新增和关闭的,而每个可用区内能看到的资源类型也是不对称并且会发生变化的(例如库存变化),因此需要有机制能动态地识别这种变化并进行相应处理。对于第二点来说,还需要开发人员对每个公有云本身的实现机制有深入的理解。

以上几个设计原则虽然并不轻松,但一旦建立完成,一方面可以在UI上做出许许多多令人赞叹的智能化设计。另一方面,公有云资源的操作可以达到毫秒级响应,在全异步的框架下,一个管理节点可以帮助用户管理成千上万个云资源,从而用户可以摒弃掉公有云控制台。

用户可以在混合云平台上做什么

对于用户来说,混合云帮助他屏蔽了许多实现细节,那么用户只需要按照场景去使用即可。在这里我们列举用户可以在混合云平台上做的事情。

灾备场景

用户指定本地数据中心的磁盘、镜像或云主机,可通过备份策略、备份组或直接手动的方式,备份到远端公有云。混合云平台帮助解决连通以及去重的问题。

互连场景

用户指定本地数据中心通过*或专线的方式连接公有云VPC,或直接连接几个公有云VPC,或把自己几个数据中心与公有云组成星形网络,互相通过内网访问。在此基础之上,用户可以让自己的业务跨云部署,或跨云使用负载均衡。至于连通的细节由混合云平台处理,用户只需要指定连通目标即可。

弹性场景

用户将本地数据中心的云主机弹到公有云,或者反过来从公有云弹到本地数据中心,从而解决业务迁移和弹性扩展问题。这个场景可以*大节省用户的资源成本,从而通过混合云平台解决数据迁移的问题。

多云管理

用户不需要再登录公有云控制台,在本地完成所有操作。本地平台还可以帮助用户解决跨帐户、跨地域管理的问题,从而可以将用户的资源管理速度提高几个数量级。

总结

本文从系统概念层面阐述了我们在研究和实践中对混合云的认知,即混合云应该是让私有云和公有云之间能进行帐号打通、网络打通、存储打通,并以流畅的用户体验*大降低用户在不同云之间的分裂体验,从而使用户能够专心于业务架构,而不用关心基础资源如何打通的问题。

针对这一全新的混合云认知,本文提出了混合云的设计目标以及围绕该目标应有的实现手段、设计原则。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速